Skip to content

Commit be219c1

Browse files
scripts: updated rt_cfg_utils for rt11xx support
Updated rt_cfg_utils for rt11xx support, and changed name formatting Signed-off-by: Daniel DeGrasse <[email protected]>
1 parent 39481fe commit be219c1

File tree

1 file changed

+140
-45
lines changed

1 file changed

+140
-45
lines changed

mcux/scripts/rt_cfg_utils.py

Lines changed: 140 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -163,31 +163,36 @@ def __init__(self, pin, peripheral_map):
163163
"""
164164
self._name = pin.attrib['name']
165165
self._properties = self._get_pin_properties(pin.find('functional_properties'))
166-
cfg_assign_xml = pin.find('functional_properties/functional_property/'
167-
'state/configuration/assign')
166+
functional_prop = pin.find('functional_properties/functional_property')
167+
cfg_assign_xml = functional_prop.find('state/configuration/assign')
168168
self._iomuxc_options = {}
169169
if cfg_assign_xml is None:
170170
# Not a configurable register. Skip.
171171
return
172172
match = re.match(r'init_([\w_]+)', cfg_assign_xml.attrib['configuration_step'])
173173
periph_name = match.group(1)
174-
match = re.match(re.escape(periph_name) + r'_(\w+)', cfg_assign_xml.attrib['register'])
175-
reg_name = match.group(1)
176-
cfg_addr = peripheral_map[periph_name].get_reg_addr(reg_name)
174+
if functional_prop.attrib.get('id') != 'software_input_on':
175+
match = re.match(re.escape(periph_name) + r'_(\w+)', cfg_assign_xml.attrib['register'])
176+
reg_name = match.group(1)
177+
match = re.match(r'SW_PAD_CTL_PAD_(\w+)', reg_name)
178+
pad_name = match.group(1)
179+
cfg_addr = peripheral_map[periph_name].get_reg_addr(reg_name)
180+
else:
181+
# This pad has mux options, but no configuration settings.
182+
cfg_addr = 0x0
183+
pad_name = self._name
177184
for connections in pin.findall('connections'):
185+
name_part = connections.attrib.get('name_part')
178186
connection = connections.find('connection')
179-
iomux_opt = IOMUXOption(connection, peripheral_map, cfg_addr)
187+
name = f"{periph_name}_{pad_name}_{name_part}"
188+
iomux_opt = IOMUXOption(connection, peripheral_map, cfg_addr, name)
180189
peripheral = connection.find('peripheral_signal_ref').attrib['peripheral']
181190
signal = connection.find('peripheral_signal_ref').attrib['signal']
182191
channel = connection.find('peripheral_signal_ref').attrib.get('channel')
183192
if channel is not None:
184193
mux_name = f"{peripheral}_{signal}, {channel}"
185194
else:
186195
mux_name = f"{peripheral}_{signal}"
187-
if iomux_opt.get_name() == '':
188-
# Use the default name of {peripheral_name}_{pin_name}
189-
iomux_opt = IOMUXOption(connection,
190-
peripheral_map, cfg_addr, name = f"{periph_name}_{self._name}")
191196
self._iomuxc_options[mux_name] = iomux_opt
192197

193198
def __repr__(self):
@@ -289,11 +294,14 @@ def _get_pin_properties(self, props):
289294
return prop_mapping
290295

291296

297+
# named tuple for GPIO port/pin
298+
GPIO = collections.namedtuple('GPIO', 'port pin')
299+
292300
class IOMUXOption:
293301
"""
294302
Internal class representing an IOMUXC option
295303
"""
296-
def __init__(self, connection, peripheral_map, cfg_reg, name = ''):
304+
def __init__(self, connection, peripheral_map, cfg_reg, name):
297305
"""
298306
Initializes an IOMUXC option object
299307
@param connection: connection XML object from signal_configuration.xml
@@ -309,8 +317,20 @@ def __init__(self, connection, peripheral_map, cfg_reg, name = ''):
309317
self._daisy_val = 0
310318
self._cfg_reg = cfg_reg
311319
self._has_extended_config = False
320+
self._has_gpr = False
312321
self._extended_config = []
313322
self._name = name
323+
# Check if this connection controls a GPIO
324+
peripheral = connection.find('peripheral_signal_ref').attrib.get('peripheral')
325+
channel = connection.find('peripheral_signal_ref').attrib.get('channel')
326+
if 'GPIO' in peripheral and channel is not None:
327+
match = re.search(r'GPIO(\d+)', peripheral)
328+
gpio_port = match.group(1)
329+
self._is_gpio = True
330+
self._gpio = GPIO(int(gpio_port), int(channel))
331+
else:
332+
self._is_gpio = False
333+
self._gpio = (0, 0)
314334
# Get connection register names
315335
for assignment in connection.findall('configuration/assign'):
316336
match = re.match(r'init_([\w_]+)', assignment.attrib['configuration_step'])
@@ -321,22 +341,21 @@ def __init__(self, connection, peripheral_map, cfg_reg, name = ''):
321341
periph = peripheral_map[periph_name]
322342
addr = periph.get_reg_addr(reg_name)
323343
value = int(assignment.attrib['bit_field_value'], 0)
324-
if not 'bit_field' in assignment.attrib:
325-
# Add register name and bit field value to extra configuration
326-
self._has_extended_config = True
327-
config = {full_name : assignment.attrib['bit_field_value']}
328-
self._extended_config.append(config)
329-
continue
330-
if assignment.attrib['bit_field'] == 'DAISY':
344+
if assignment.attrib.get('bit_field') == 'DAISY':
331345
self._daisy = addr
332346
self._daisy_val = value
333-
elif assignment.attrib['bit_field'] == 'MUX_MODE':
347+
elif assignment.attrib.get('bit_field') == 'MUX_MODE':
334348
self._mux = addr
335349
self._mux_val = value
336-
register = periph.get_register(reg_name)
337-
# Create IOMUXC name for this connection
338-
if self._name == '':
339-
self._name = self._generate_iomuxc_name(periph, register, value)
350+
elif periph_name == 'IOMUXC_GPR':
351+
# GPR register can be used as a secondary pinmux selection,
352+
# record this setting
353+
self._has_gpr = True
354+
self._gpr_reg = addr
355+
gpr_mask = int(assignment.attrib.get('bit_field_mask'), 0)
356+
# Calculate gpr bit shift
357+
self._gpr_shift = ((gpr_mask) & -(gpr_mask)).bit_length() - 1
358+
self._gpr_val = int(assignment.attrib.get('bit_field_value'), 0)
340359
else:
341360
# Add register name and bit field value to extra configuration
342361
self._has_extended_config = True
@@ -349,6 +368,8 @@ def __repr__(self):
349368
"""
350369
if self._has_extended_config:
351370
return "IOMUXOpt(%s, 0x%X = %d, ExtCfg)" % (self._name, self._mux, self._mux_val)
371+
elif self._has_gpr:
372+
return "IOMUXOpt(%s, 0x%X = %d, GPR)" % (self._name, self._mux, self._mux_val)
352373
return "IOMUXOpt(%s, 0x%X = %d)" % (self._name, self._mux, self._mux_val)
353374

354375
def __hash__(self):
@@ -387,7 +408,20 @@ def get_mux_reg(self):
387408
Get the mux reg for this iomux option
388409
"""
389410
return self._mux
390-
411+
412+
def is_gpio(self):
413+
"""
414+
return True if this iomux option is for a GPIO
415+
"""
416+
return self._is_gpio
417+
418+
def gpio(self):
419+
"""
420+
Get iomux gpio port and pin as a tuple of (port,pin)
421+
only valid if is_gpio is True
422+
"""
423+
return self._gpio
424+
391425
def get_mux_val(self):
392426
"""
393427
Get the mux value for this iomux option
@@ -412,6 +446,30 @@ def get_cfg_reg(self):
412446
"""
413447
return self._cfg_reg
414448

449+
def has_gpr(self):
450+
"""
451+
Return true if iomux option has associated GPR configuration requirement
452+
"""
453+
return self._has_gpr
454+
455+
def gpr_reg(self):
456+
"""
457+
If has_gpr() is true, return GPR register address
458+
"""
459+
return self._gpr_reg
460+
461+
def gpr_shift(self):
462+
"""
463+
If has_gpr() is true, return shift on GPR register value
464+
"""
465+
return self._gpr_shift
466+
467+
def gpr_val(self):
468+
"""
469+
If has_gpr() is true, return GPR register value
470+
"""
471+
return self._gpr_val
472+
415473
def has_extended_config(self):
416474
"""
417475
Return true if the iomux option requires extended register configuration
@@ -424,21 +482,6 @@ def get_extended_config(self):
424482
"""
425483
return self._extended_config
426484

427-
def _generate_iomuxc_name(self, periph, reg, mux_val):
428-
"""
429-
Extracts the iomuxc name for a connection from the SW_MUX_CTL_PAD
430-
register that is being set. The register description is used to generate
431-
the final iomuxc name, like in MCUXpresso config tools
432-
@param periph: peripheral object with the SW_MUX_CTL_PAD register
433-
@param reg: register object holding the SW_MUX_CTL_PAD register object
434-
@param mux_val: mux value being selected in register
435-
"""
436-
pad_name = re.match(r'SW_MUX_CTL_PAD_(\w+)', reg.get_name()).group(1)
437-
description = reg.get_bit_field_value_description('MUX_MODE', mux_val)
438-
mux_name = re.search(r': (\w+) of instance', description).group(1)
439-
return f"{periph.get_name()}_{pad_name}_{mux_name}"
440-
441-
442485
class PinGroup:
443486
"""
444487
Internal class representing pin group
@@ -680,6 +723,54 @@ def get_part_num(self):
680723
"""
681724
return self._soc_sku
682725

726+
def write_gpio_mux(self, outputfile):
727+
"""
728+
Write pinctrl defintions for GPIO mux. These defintions map GPIO port
729+
and pin combinations to iomuxc options. Note that these defintions are
730+
not indended to be used directly, and will likely need to be hand edited.
731+
@param outputfile file to write gpio dtsi file to
732+
"""
733+
# Layered dictionary of gpio mux options. The root keys
734+
# are the port names, and those port names map to
735+
# dictionaries of pin->iomux option mappings
736+
gpio_map = collections.defaultdict(lambda: {})
737+
with open(outputfile, "w", encoding='utf8') as gpio_dsti:
738+
# Write header
739+
gpio_dsti.write(f"/*\n"
740+
f" * File created by {os.path.basename(__file__)}\n"
741+
" * not intended for direct usage. Hand edit these DTS\n"
742+
" * nodes as needed to integrate them into Zephyr.\n"
743+
" */\n\n")
744+
for pin in sorted(self._signal_map.values()):
745+
for iomux_opt in sorted(pin.get_mux_options()):
746+
if iomux_opt.is_gpio():
747+
gpio = iomux_opt.gpio()
748+
if 'CM7' in iomux_opt.get_name():
749+
gpio_map[f"{gpio.port}_CM7"][gpio.pin] = iomux_opt
750+
else:
751+
gpio_map[str(gpio.port)][gpio.pin] = iomux_opt
752+
# Now write SOC level GPIO pinmux definitions. These are required
753+
# so that gpio driver is capable of selecting pinmux options when
754+
# a gpio pin is configured.
755+
gpio_dsti.write("/*\n"
756+
" * GPIO pinmux options. These options define the pinmux settings\n"
757+
" * for GPIO ports on the package, so that the GPIO driver can\n"
758+
" * select GPIO mux options during GPIO configuration.\n"
759+
" */\n\n")
760+
for port in sorted(gpio_map):
761+
dts_node = (f"&gpio{port}{{\n"
762+
"\tpinmux = ")
763+
for pin in sorted(gpio_map[port]):
764+
iomux_opt = gpio_map[port][pin]
765+
dts_node += f"<&{iomux_opt.get_name().lower()}>,\n\t\t"
766+
dts_node = re.sub(r',\n\t\t$', ";\n", dts_node)
767+
# end group
768+
dts_node += "};\n\n"
769+
gpio_dsti.write(dts_node)
770+
gpio_dsti.close()
771+
772+
773+
683774
def write_pinctrl_defs(self, outputfile):
684775
"""
685776
Writes a pinctrl dtsi file that defines all pinmux options. The board
@@ -743,11 +834,16 @@ def write_pinctrl_defs(self, outputfile):
743834
print(f"Warning: unmatched signal pin name {iomuxc_name}")
744835
reg_type = ''
745836
dts_node += f"\t\t{reg_type};\n"
837+
if iomux_opt.has_gpr():
838+
gpr_reg = iomux_opt.gpr_reg()
839+
gpr_shift = iomux_opt.gpr_shift()
840+
gpr_val = iomux_opt.gpr_val()
841+
# Add GPR configuration
842+
dts_node += f"\t\tgpr = <0x{gpr_reg:x} 0x{gpr_shift:x} 0x{gpr_val:x}>;\n"
746843
dts_node += "\t};\n"
747844
# Write iomuxc dts node to file
748845
soc_dtsi.write(dts_node)
749-
soc_dtsi.write("};\n\n")
750-
soc_dtsi.close()
846+
soc_dtsi.write("};\n\n")
751847

752848
def write_pinctrl_groups(self, mexfile, outputfile):
753849
"""
@@ -876,10 +972,9 @@ def _load_signal_map(self, xml):
876972
iomuxc_options = {}
877973
for pad in pads:
878974
pad_name = pad.attrib['name']
879-
if len(pad.findall('functional_properties/functional_property')) == 0:
880-
# Not a configurable pad. Continue
881-
continue
882-
iomuxc_options[pad_name] = SignalPin(pad, self._peripheral_map)
975+
# Verify signal pad is configurable
976+
if len(pad.findall('functional_properties/functional_property')) != 0:
977+
iomuxc_options[pad_name] = SignalPin(pad, self._peripheral_map)
883978
return iomuxc_options
884979

885980

0 commit comments

Comments
 (0)