Skip to content

Commit 3320572

Browse files
committed
[genpinmap] Enhance arguments
Signed-off-by: Frederic.Pillon <[email protected]>
1 parent da6cd5a commit 3320572

File tree

3 files changed

+162
-112
lines changed

3 files changed

+162
-112
lines changed

src/genpinmap/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
config.json

src/genpinmap/README.md

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
# genpinmap
22

3-
This script is able to generate the `PeripheralPins.c` for a specific board.
3+
By default,this script is able to generate `PeripheralPins.c` for all xml files description available in
4+
[STM32CubeMX](http://www.st.com/en/development-tools/stm32cubemx.html) directory defined in `config.json`.
45

5-
After file generation, review it carefully and please report any issue
6-
[here](https://github.com/stm32duino/Arduino_Tools/issues)
6+
After file generation, review them carefully and please report any issue
7+
[here](https://github.com/stm32duino/Arduino_Tools/issues).
78

8-
Once generated, you should comment a line if the pin is generated<br>
9-
several times for the same IP or if the pin should not be used<br>
10-
(overlaid with some HW on the board, for instance)
9+
Once generated, you should comment a line if the pin is generated several times for the same IP or if the pin should not be used
10+
(overlaid with some HW on the board, for instance).
1111

12-
Usage: `python genpinmap_arduino.py <Name> <product xml file name>`
13-
- `<Name>` is the name of the directory where `PeripheralPins.c` will be generated under _./Arduino_ directory
14-
- `<product xml file name>` is the STM32 file description in [STM32CubeMX](http://www.st.com/en/development-tools/stm32cubemx.html)
12+
usage: `python genpinmap_arduino.py [-h] [-l | -m xml]`
1513

16-
**!! This xml file contains non alpha characters in its name, you should call it with quotes**
14+
optional arguments:
15+
16+
`-h, --help` show this help message and exit<br>
17+
`-l, --list` list available xml files description in [STM32CubeMX](http://www.st.com/en/development-tools/stm32cubemx.html)<br>
18+
`-m xml, --mcu xml` Generate `PeripheralPins.c` for specified mcu xml file description
19+
in [STM32CubeMX](http://www.st.com/en/development-tools/stm32cubemx.html).
20+
**This xml file contains non alpha characters in its name, you should call it with double quotes**
21+
22+
All generated file are available under _./Arduino/<mcu_name>_ directory

src/genpinmap/genpinmap_arduino.py

+145-102
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
import sys
2-
import re
3-
import os
1+
import argparse
42
import datetime
3+
import fnmatch
54
import json
5+
import os
6+
import re
7+
import sys
8+
import textwrap
69
from xml.dom import minidom
710
from xml.dom.minidom import parse, Node
8-
io_list = [] #'PIN','name'
11+
from argparse import RawTextHelpFormatter
12+
mcu_file=""
13+
mcu_list = [] #'name'
14+
io_list = [] #'PIN','name'
915
adclist = [] #'PIN','name','ADCSignal'
1016
daclist = [] #'PIN','name','DACSignal'
1117
i2cscl_list = [] #'PIN','name','I2CSCLSignal'
@@ -24,7 +30,6 @@
2430
eth_list = [] #'PIN','name','ETH'
2531
qspi_list = [] #'PIN','name','QUADSPI'
2632

27-
2833
def find_gpio_file(xmldoc):
2934
res = 'ERROR'
3035
itemlist = xmldoc.getElementsByTagName('IP')
@@ -35,7 +40,7 @@ def find_gpio_file(xmldoc):
3540
return res
3641

3742
def get_gpio_af_num(xml, pintofind, iptofind):
38-
if 'STM32F10' in sys.argv[2]:
43+
if 'STM32F10' in mcu_file:
3944
return get_gpio_af_numF1(xml, pintofind, iptofind)
4045
# xml = parse('GPIO-STM32L051_gpio_v1_0_Modes.xml')
4146
#xml = parse(gpiofile)
@@ -397,7 +402,7 @@ def print_uart(xml, l):
397402
#2nd element is the UART_XX signal
398403
b=p[2].split('_')[0]
399404
s1 += "%-9s" % (b[:len(b)-1] + b[len(b)-1:] + ',')
400-
if 'STM32F10' in sys.argv[2] and l == uartrx_list:
405+
if 'STM32F10' in mcu_file and l == uartrx_list:
401406
s1 += 'STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, '
402407
else:
403408
s1 += 'STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, '
@@ -447,7 +452,7 @@ def print_can(xml, l):
447452
instance = p[2].split('_')[0].replace("CAN", "")
448453
if len(instance) == 0:
449454
instance = '1'
450-
if 'STM32F10' in sys.argv[2] and l == canrd_list:
455+
if 'STM32F10' in mcu_file and l == canrd_list:
451456
s1 += 'CAN' + instance + ', STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, '
452457
else:
453458
s1 += 'CAN' + instance + ', STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, '
@@ -541,32 +546,35 @@ def sort_my_lists():
541546

542547
return
543548

544-
# START MAIN PROGRAM
549+
def clean_all_lists():
550+
del io_list[:]
551+
del adclist[:]
552+
del daclist[:]
553+
del i2cscl_list[:]
554+
del i2csda_list[:]
555+
del pwm_list[:]
556+
del uarttx_list[:]
557+
del uartrx_list[:]
558+
del uartcts_list[:]
559+
del uartrts_list[:]
560+
del spimosi_list[:]
561+
del spimiso_list[:]
562+
del spissel_list[:]
563+
del spisclk_list[:]
564+
del cantd_list[:]
565+
del canrd_list[:]
566+
del eth_list[:]
567+
del qspi_list[:]
568+
569+
# main
545570
cur_dir = os.getcwd()
546571
out_filename = 'PeripheralPins.c'
547572
config_filename = 'config.json'
548573

549-
if len(sys.argv) < 3:
550-
print("Usage: " + sys.argv[0] + " <BOARD_NAME> <product xml file name>")
551-
print(" - <BOARD_NAME> is the name of the board as it will be named in mbed")
552-
print(" - <product xml file name> is the STM32 file description in Cube MX")
553-
print(" !!This xml file contains non alpha characters in its name, you should call it with quotes")
554-
print("")
555-
print(" This script is able to generate the %s for a specific board" % out_filename )
556-
print(" After file generation, review it carefully and ")
557-
print(" please report any issue to github:")
558-
print(" https://github.com/fpistm/stm32_tools/issues")
559-
print("")
560-
print(" Once generated, you should comment a line if the pin is generated ")
561-
print(" several times for the same IP")
562-
print(" or if the pin should not be used (overlaid with some HW on the board, ")
563-
print(" for instance)")
564-
quit()
565-
566574
try:
567575
config_file = open(config_filename, "r")
568576
except IOError:
569-
print("Please set your configuration in %s file" % config_filename)
577+
print("Please set your configuration in '%s' file" % config_filename)
570578
config_file = open(config_filename, "w")
571579
if sys.platform.startswith('win32'):
572580
print("Platform is Windows")
@@ -588,84 +596,119 @@ def sort_my_lists():
588596
config_file.close()
589597
cubemxdir = config["CUBEMX_DIRECTORY"]
590598

591-
cubemxdirIP = os.path.join(cubemxdir, 'IP')
592-
input_file_name = os.path.join(cubemxdir, sys.argv[2])
593-
out_path = os.path.join(cur_dir, 'Arduino', sys.argv[1])
594-
output_filename = os.path.join(out_path, out_filename)
599+
# by default, generate for all mcu xml files description
600+
parser = argparse.ArgumentParser(
601+
description=textwrap.dedent('''\
602+
By default, generate %s for all xml files description available in
603+
STM32CubeMX directory defined in '%s':
604+
\t%s''' % (out_filename, config_filename, cubemxdir)),
605+
epilog=textwrap.dedent('''\
606+
After files generation, review them carefully and please report any issue to github:
607+
\thttps://github.com/stm32duino/Arduino_Tools/issues\n
608+
Once generated, you have to comment a line if the pin is generated several times
609+
for the same IP or if the pin should not be used (overlaid with some HW on the board,
610+
for instance)'''),
611+
formatter_class=RawTextHelpFormatter)
612+
group = parser.add_mutually_exclusive_group()
613+
group.add_argument("-l", "--list", help="list available xml files description in STM32CubeMX", action="store_true")
614+
group.add_argument("-m", "--mcu", metavar='xml', help=textwrap.dedent('''\
615+
Generate %s for specified mcu xml file description
616+
in STM32CubeMX. This xml file contains non alpha characters in
617+
its name, you should call it with double quotes''' % out_filename))
618+
args = parser.parse_args()
595619

596-
#check input file exists
597620
if not(os.path.isdir(cubemxdir)):
598621
print ("\n ! ! ! Cube Mx seems not to be installed or not at the requested location")
599-
print ("\n ! ! ! please check the value you set for cubemxdir variable at the top of " + sys.argv[0] + " file")
600-
quit()
601-
if not(os.path.isfile(input_file_name)):
602-
print ('\n ! ! ! ' + sys.argv[2] + ' file not found')
603-
print ("\n ! ! ! Check in " + cubemxdir + " the correct name of this file")
604-
print ("\n ! ! ! You may use double quotes for this file if it contains special characters")
622+
print ("\n ! ! ! please check the value you set for 'CUBEMX_DIRECTORY' in '%s' file" % config_filename)
605623
quit()
606624

607-
#open input file
608-
print (" * * * Opening input file...")
609-
if not(os.path.isdir(out_path)):
610-
os.makedirs(out_path)
611-
xmldoc = minidom.parse(input_file_name)
612-
itemlist = xmldoc.getElementsByTagName('Pin')
613-
#open output file
614-
if (os.path.isfile(output_filename)):
615-
print (" * * * * Requested %s file already exists and will be overwritten" % out_filename)
616-
os.remove(output_filename)
617-
618-
out_file = open(output_filename, 'w')
619-
620-
gpiofile = find_gpio_file(xmldoc)
621-
if gpiofile == 'ERROR':
625+
cubemxdirIP = os.path.join(cubemxdir, 'IP')
626+
627+
if args.mcu:
628+
#check input file exists
629+
if not(os.path.isfile(os.path.join(cubemxdir, args.mcu))):
630+
print ("\n ! ! ! " + args.mcu + " file not found")
631+
print ("\n ! ! ! Check in " + cubemxdir + " the correct name of this file")
632+
print ("\n ! ! ! You may use double quotes for this file if it contains special characters")
633+
quit()
634+
mcu_list.append(args.mcu)
635+
else:
636+
mcu_list=fnmatch.filter(os.listdir(cubemxdir), 'STM32*.xml')
637+
638+
if args.list:
639+
print("Available xml files description: %i" % len(mcu_list))
640+
for f in mcu_list:
641+
print(f)
622642
quit()
623-
xml = parse(os.path.join(cubemxdirIP, 'GPIO-' + gpiofile + '_Modes.xml'))
624-
print (" * * * Getting pins and Ips for the xml file...")
625-
pinregex=r'^(P[A-Z][0-9][0-5]?)'
626-
for s in itemlist:
627-
m = re.match(pinregex, s.attributes['Name'].value)
628-
if m:
629-
pin = m.group(0)[:2] + '_' + m.group(0)[2:] # pin formatted P<port>_<number>: PF_O
630-
name = s.attributes['Name'].value.strip() # full name: "PF0 / OSC_IN"
631-
if s.attributes['Type'].value == "I/O":
632-
store_pin(pin, name)
633-
else:
634-
continue
635-
siglist = s.getElementsByTagName('Signal')
636-
for a in siglist:
637-
sig = a.attributes['Name'].value.strip()
638-
if "ADC" in sig:
639-
#store ADC pin
640-
store_adc(pin, name, sig)
641-
if all(["DAC" in sig, "_OUT" in sig]):
642-
#store DAC
643-
store_dac(pin, name, sig)
644-
if "I2C" in sig:
645-
#store DAC
646-
store_i2c(pin, name, sig)
647-
if re.match('^TIM', sig) is not None: #ignore HRTIM
648-
#store PWM
649-
store_pwm(pin, name, sig)
650-
if re.match('^(LPU|US|U)ART', sig) is not None:
651-
store_uart(pin, name, sig)
652-
if "SPI" in sig:
653-
store_spi(pin, name, sig)
654-
if "CAN" in sig:
655-
store_can(pin, name, sig)
656-
if "ETH" in sig:
657-
store_eth(pin, name, sig)
658-
if "QUADSPI" in sig:
659-
store_qspi(pin, name, sig)
660-
661-
print (" * * * Sorting lists...")
662-
sort_my_lists()
663-
664-
print (" * * * Printing lists...")
665-
print_header()
666-
print_all_lists()
667-
out_file.close()
668-
669-
nb_pin = (len(io_list))
670-
print ("nb of I/O pins: %i" % nb_pin)
671-
print ('\n * * * ' + sys.argv[1]+' OK')
643+
644+
for mcu_file in mcu_list:
645+
print("Generate %s for '%s'" % (out_filename, mcu_file))
646+
input_file_name = os.path.join(cubemxdir, mcu_file)
647+
out_path = os.path.join(cur_dir, 'Arduino', os.path.splitext(mcu_file)[0])
648+
output_filename = os.path.join(out_path, out_filename)
649+
if not(os.path.isdir(out_path)):
650+
os.makedirs(out_path)
651+
652+
#open input file
653+
#print (" * * * Opening input file...")
654+
xmldoc = minidom.parse(input_file_name)
655+
itemlist = xmldoc.getElementsByTagName('Pin')
656+
#open output file
657+
if (os.path.isfile(output_filename)):
658+
#print (" * * * * Requested %s file already exists and will be overwritten" % out_filename)
659+
os.remove(output_filename)
660+
661+
out_file = open(output_filename, 'w')
662+
663+
gpiofile = find_gpio_file(xmldoc)
664+
if gpiofile == 'ERROR':
665+
print("Could not find GPIO file")
666+
quit()
667+
668+
xml = parse(os.path.join(cubemxdirIP, 'GPIO-' + gpiofile + '_Modes.xml'))
669+
print (" * * * Getting pins and Ips for the xml file...")
670+
pinregex=r'^(P[A-Z][0-9][0-5]?)'
671+
for s in itemlist:
672+
m = re.match(pinregex, s.attributes['Name'].value)
673+
if m:
674+
pin = m.group(0)[:2] + '_' + m.group(0)[2:] # pin formatted P<port>_<number>: PF_O
675+
name = s.attributes['Name'].value.strip() # full name: "PF0 / OSC_IN"
676+
if s.attributes['Type'].value == "I/O":
677+
store_pin(pin, name)
678+
else:
679+
continue
680+
siglist = s.getElementsByTagName('Signal')
681+
for a in siglist:
682+
sig = a.attributes['Name'].value.strip()
683+
if "ADC" in sig:
684+
store_adc(pin, name, sig)
685+
if all(["DAC" in sig, "_OUT" in sig]):
686+
store_dac(pin, name, sig)
687+
if "I2C" in sig:
688+
store_i2c(pin, name, sig)
689+
if re.match('^TIM', sig) is not None: #ignore HRTIM
690+
store_pwm(pin, name, sig)
691+
if re.match('^(LPU|US|U)ART', sig) is not None:
692+
store_uart(pin, name, sig)
693+
if "SPI" in sig:
694+
store_spi(pin, name, sig)
695+
if "CAN" in sig:
696+
store_can(pin, name, sig)
697+
if "ETH" in sig:
698+
store_eth(pin, name, sig)
699+
if "QUADSPI" in sig:
700+
store_qspi(pin, name, sig)
701+
702+
#print (" * * * Sorting lists...")
703+
sort_my_lists()
704+
705+
#print (" * * * Printing lists...")
706+
print_header()
707+
print_all_lists()
708+
709+
nb_pin = (len(io_list))
710+
print ("nb of I/O pins: %i" % nb_pin)
711+
print ('\n * * * ' + mcu_file +' OK')
712+
clean_all_lists()
713+
714+
out_file.close()

0 commit comments

Comments
 (0)