1
- import sys
2
- import re
3
- import os
1
+ import argparse
4
2
import datetime
3
+ import fnmatch
5
4
import json
5
+ import os
6
+ import re
7
+ import sys
8
+ import textwrap
6
9
from xml .dom import minidom
7
10
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'
9
15
adclist = [] #'PIN','name','ADCSignal'
10
16
daclist = [] #'PIN','name','DACSignal'
11
17
i2cscl_list = [] #'PIN','name','I2CSCLSignal'
24
30
eth_list = [] #'PIN','name','ETH'
25
31
qspi_list = [] #'PIN','name','QUADSPI'
26
32
27
-
28
33
def find_gpio_file (xmldoc ):
29
34
res = 'ERROR'
30
35
itemlist = xmldoc .getElementsByTagName ('IP' )
@@ -35,7 +40,7 @@ def find_gpio_file(xmldoc):
35
40
return res
36
41
37
42
def get_gpio_af_num (xml , pintofind , iptofind ):
38
- if 'STM32F10' in sys . argv [ 2 ] :
43
+ if 'STM32F10' in mcu_file :
39
44
return get_gpio_af_numF1 (xml , pintofind , iptofind )
40
45
# xml = parse('GPIO-STM32L051_gpio_v1_0_Modes.xml')
41
46
#xml = parse(gpiofile)
@@ -397,7 +402,7 @@ def print_uart(xml, l):
397
402
#2nd element is the UART_XX signal
398
403
b = p [2 ].split ('_' )[0 ]
399
404
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 :
401
406
s1 += 'STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, '
402
407
else :
403
408
s1 += 'STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, '
@@ -447,7 +452,7 @@ def print_can(xml, l):
447
452
instance = p [2 ].split ('_' )[0 ].replace ("CAN" , "" )
448
453
if len (instance ) == 0 :
449
454
instance = '1'
450
- if 'STM32F10' in sys . argv [ 2 ] and l == canrd_list :
455
+ if 'STM32F10' in mcu_file and l == canrd_list :
451
456
s1 += 'CAN' + instance + ', STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, '
452
457
else :
453
458
s1 += 'CAN' + instance + ', STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, '
@@ -541,32 +546,35 @@ def sort_my_lists():
541
546
542
547
return
543
548
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
545
570
cur_dir = os .getcwd ()
546
571
out_filename = 'PeripheralPins.c'
547
572
config_filename = 'config.json'
548
573
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
-
566
574
try :
567
575
config_file = open (config_filename , "r" )
568
576
except IOError :
569
- print ("Please set your configuration in %s file" % config_filename )
577
+ print ("Please set your configuration in '%s' file" % config_filename )
570
578
config_file = open (config_filename , "w" )
571
579
if sys .platform .startswith ('win32' ):
572
580
print ("Platform is Windows" )
@@ -588,84 +596,119 @@ def sort_my_lists():
588
596
config_file .close ()
589
597
cubemxdir = config ["CUBEMX_DIRECTORY" ]
590
598
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
+ \t https://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 ()
595
619
596
- #check input file exists
597
620
if not (os .path .isdir (cubemxdir )):
598
621
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 )
605
623
quit ()
606
624
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 )
622
642
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