3
3
import json
4
4
import re
5
5
import string
6
+ import subprocess
6
7
import sys
7
8
import textwrap
8
9
from argparse import RawTextHelpFormatter
@@ -303,7 +304,7 @@ def print_periph_header():
303
304
s = """{}
304
305
/*
305
306
* Automatically generated from {}
306
- * CubeMX DB version {} release {}
307
+ * CubeMX DB release {}
307
308
*/
308
309
#include "Arduino.h"
309
310
#include "{}.h"
@@ -322,8 +323,7 @@ def print_periph_header():
322
323
""" .format (
323
324
license_header ,
324
325
mcu_file .name ,
325
- cubemx_db_version ,
326
- cubemx_db_release ,
326
+ db_release ,
327
327
re .sub ("\\ .c$" , "" , periph_c_filename ),
328
328
)
329
329
periph_c_file .write (s )
@@ -1321,59 +1321,160 @@ def parse_pins():
1321
1321
store_sd (pin , name , sig )
1322
1322
1323
1323
1324
+ # Config management
1325
+ def create_config ():
1326
+ # Create a Json file for a better path management
1327
+ try :
1328
+ print ("Please set your configuration in '{}' file" .format (config_filename ))
1329
+ config_file = open (config_filename , "w" , newline = "\n " )
1330
+ if sys .platform .startswith ("win32" ):
1331
+ print ("Platform is Windows" )
1332
+ cubemxdir = Path (
1333
+ r"C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeMX"
1334
+ )
1335
+ elif sys .platform .startswith ("linux" ):
1336
+ print ("Platform is Linux" )
1337
+ cubemxdir = Path .home () / "STM32CubeMX"
1338
+ elif sys .platform .startswith ("darwin" ):
1339
+ print ("Platform is Mac OSX" )
1340
+ cubemxdir = Path (
1341
+ "/Applications/STMicroelectronics/STM32CubeMX.app/Contents/Resources"
1342
+ )
1343
+ else :
1344
+ print ("Platform unknown" )
1345
+ cubemxdir = "<Set CubeMX install directory>"
1346
+ config_file .write (
1347
+ json .dumps (
1348
+ {
1349
+ "CUBEMX_DIRECTORY" : str (cubemxdir ),
1350
+ "REPO_LOCAL_PATH" : str (repo_local_path ),
1351
+ },
1352
+ indent = 2 ,
1353
+ )
1354
+ )
1355
+ config_file .close ()
1356
+ except IOError :
1357
+ print ("Failed to open " + config_filename )
1358
+ exit (1 )
1359
+
1360
+
1361
+ def check_config ():
1362
+ global cubemxdir
1363
+ global repo_local_path
1364
+ global repo_path
1365
+
1366
+ if config_filename .is_file ():
1367
+ try :
1368
+ config_file = open (config_filename , "r" )
1369
+ config = json .load (config_file )
1370
+ config_file .close ()
1371
+
1372
+ conf = config ["REPO_LOCAL_PATH" ]
1373
+ if conf :
1374
+ if conf != "" :
1375
+ repo_local_path = Path (conf )
1376
+ repo_path = repo_local_path / repo_name
1377
+ conf = config ["CUBEMX_DIRECTORY" ]
1378
+ if conf :
1379
+ cubemxdir = Path (conf )
1380
+ except IOError :
1381
+ print ("Failed to open " + config_filename )
1382
+ else :
1383
+ create_config ()
1384
+
1385
+
1386
+ def manage_repo ():
1387
+ global db_release
1388
+ repo_local_path .mkdir (parents = True , exist_ok = True )
1389
+
1390
+ print ("Updating " + repo_name + "..." )
1391
+ try :
1392
+ if not args .skip :
1393
+ if repo_path .is_dir ():
1394
+ # Get new tags from the remote
1395
+ git_cmds = [
1396
+ ["git" , "-C" , repo_path , "clean" , "-fdx" ],
1397
+ ["git" , "-C" , repo_path , "fetch" ],
1398
+ ["git" , "-C" , repo_path , "reset" , "--hard" , "origin/master" ],
1399
+ ]
1400
+ else :
1401
+ # Clone it as it does not exists yet
1402
+ git_cmds = [["git" , "-C" , repo_local_path , "clone" , gh_url ]]
1403
+
1404
+ for cmd in git_cmds :
1405
+ subprocess .check_output (cmd ).decode ("utf-8" )
1406
+ if repo_path .is_dir ():
1407
+ # Get tag
1408
+ sha1_id = (
1409
+ subprocess .check_output (
1410
+ ["git" , "-C" , repo_path , "rev-list" , "--tags" , "--max-count=1" ]
1411
+ )
1412
+ .decode ("utf-8" )
1413
+ .strip ()
1414
+ )
1415
+ version_tag = (
1416
+ subprocess .check_output (
1417
+ ["git" , "-C" , repo_path , "describe" , "--tags" , sha1_id ]
1418
+ )
1419
+ .decode ("utf-8" )
1420
+ .strip ()
1421
+ )
1422
+ subprocess .check_output (
1423
+ ["git" , "-C" , repo_path , "checkout" , version_tag ],
1424
+ stderr = subprocess .DEVNULL ,
1425
+ )
1426
+ db_release = version_tag
1427
+ return True
1428
+ except subprocess .CalledProcessError as e :
1429
+ print ("Command {} failed with error code {}" .format (e .cmd , e .returncode ))
1430
+ return False
1431
+
1432
+
1324
1433
# main
1325
1434
cur_dir = Path .cwd ()
1326
1435
templates_dir = cur_dir / "templates"
1327
1436
periph_c_filename = "PeripheralPins.c"
1328
1437
pinvar_h_filename = "PinNamesVar.h"
1329
- config_filename = "config.json"
1438
+ config_filename = Path ( "config.json" )
1330
1439
variant_h_filename = "variant.h"
1331
1440
variant_cpp_filename = "variant.cpp"
1441
+ repo_local_path = cur_dir / "repo"
1442
+ gh_url = "https://github.com/STMicroelectronics/STM32_open_pin_data"
1443
+ repo_name = gh_url .rsplit ("/" , 1 )[- 1 ]
1444
+ repo_path = repo_local_path / repo_name
1445
+ db_release = "Unknown"
1332
1446
1333
- try :
1334
- config_file = open (config_filename , "r" )
1335
- except IOError :
1336
- print ("Please set your configuration in '{}' file" .format (config_filename ))
1337
- config_file = open (config_filename , "w" , newline = "\n " )
1338
- if sys .platform .startswith ("win32" ):
1339
- print ("Platform is Windows" )
1340
- cubemxdir = Path (r"C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeMX" )
1341
- elif sys .platform .startswith ("linux" ):
1342
- print ("Platform is Linux" )
1343
- cubemxdir = Path .home () / "STM32CubeMX"
1344
- elif sys .platform .startswith ("darwin" ):
1345
- print ("Platform is Mac OSX" )
1346
- cubemxdir = Path (
1347
- "/Applications/STMicroelectronics/STM32CubeMX.app/Contents/Resources"
1348
- )
1349
- else :
1350
- print ("Platform unknown" )
1351
- cubemxdir = "<Set CubeMX install directory>"
1352
- config_file .write (json .dumps ({"CUBEMX_DIRECTORY" : str (cubemxdir )}))
1353
- config_file .close ()
1354
- exit (1 )
1355
-
1356
- config = json .load (config_file )
1357
- config_file .close ()
1358
- cubemxdir = Path (config ["CUBEMX_DIRECTORY" ])
1447
+ check_config ()
1359
1448
1360
1449
# By default, generate for all mcu xml files description
1361
1450
parser = argparse .ArgumentParser (
1362
1451
description = textwrap .dedent (
1363
1452
"""\
1364
- By default, generate {} and {} for all xml files description available in
1365
- STM32CubeMX directory defined in '{}':
1366
- \t {}""" .format (
1367
- periph_c_filename , pinvar_h_filename , config_filename , cubemxdir
1453
+ By default, generate {}, {}, {} and {}
1454
+ for all xml files description available in STM32CubeMX internal database.
1455
+ Internal database path must be defined in {}.
1456
+ It can be the one from STM32CubeMX directory if defined:
1457
+ \t {}
1458
+ or the one from GitHub:
1459
+ \t {}
1460
+
1461
+ """ .format (
1462
+ periph_c_filename ,
1463
+ pinvar_h_filename ,
1464
+ variant_cpp_filename ,
1465
+ variant_h_filename ,
1466
+ config_filename ,
1467
+ cubemxdir ,
1468
+ gh_url ,
1368
1469
)
1369
1470
),
1370
1471
epilog = textwrap .dedent (
1371
1472
"""\
1372
- After files generation, review them carefully and please report any issue to github :
1473
+ After files generation, review them carefully and please report any issue to GitHub :
1373
1474
\t https://github.com/stm32duino/Arduino_Tools/issues\n
1374
- Once generated, you have to comment a line if the pin is generated several times
1375
- for the same IP or if the pin should not be used (overlaid with some HW on the board,
1376
- for instance) """
1475
+ Once generated, you can comment a line if the pin should not be used
1476
+ (overlaid with some HW on the board, for instance) and update all undefined pins
1477
+ in variant. """
1377
1478
),
1378
1479
formatter_class = RawTextHelpFormatter ,
1379
1480
)
@@ -1390,48 +1491,84 @@ def parse_pins():
1390
1491
metavar = "xml" ,
1391
1492
help = textwrap .dedent (
1392
1493
"""\
1393
- Generate {} and {} for specified mcu xml file description
1394
- in STM32CubeMX. This xml file contains non alpha characters in
1395
- its name, you should call it with double quotes""" .format (
1396
- periph_c_filename , pinvar_h_filename
1494
+ Generate {}, {}, {} and {}
1495
+ for specified mcu xml file description in STM32CubeMX.
1496
+ This xml file can contain non alpha characters in its name,
1497
+ you should call it with double quotes""" .format (
1498
+ periph_c_filename ,
1499
+ pinvar_h_filename ,
1500
+ variant_cpp_filename ,
1501
+ variant_h_filename ,
1502
+ )
1503
+ ),
1504
+ )
1505
+
1506
+ parser .add_argument (
1507
+ "-c" ,
1508
+ "--cube" ,
1509
+ help = textwrap .dedent (
1510
+ """\
1511
+ Use STM32CubeMX internal database. Default use GitHub {} repository.
1512
+ """ .format (
1513
+ repo_name
1397
1514
)
1398
1515
),
1516
+ action = "store_true" ,
1517
+ )
1518
+ parser .add_argument (
1519
+ "-s" ,
1520
+ "--skip" ,
1521
+ help = "Skip {} clone/fetch" .format (repo_name ),
1522
+ action = "store_true" ,
1399
1523
)
1400
1524
args = parser .parse_args ()
1401
1525
1402
- if not (cubemxdir .is_dir ()):
1403
- print ("\n Cube Mx seems not to be installed or not at the requested location." )
1404
- print (
1405
- "\n Please check the value you set for 'CUBEMX_DIRECTORY' in '{}' file." .format (
1406
- config_filename
1526
+ # Using GitHub repo is the preferred way, CubeMX used as a fallback
1527
+ fallback = False
1528
+ if not args .cube :
1529
+ if manage_repo ():
1530
+ dirMCU = repo_path / "mcu"
1531
+ dirIP = dirMCU / "IP"
1532
+ else :
1533
+ fallback = True
1534
+ if fallback or args .cube :
1535
+ if not (cubemxdir .is_dir ()):
1536
+ print (
1537
+ """
1538
+ Cube Mx seems not to be installed or not at the specified location.
1539
+
1540
+ Please check the value set for 'CUBEMX_DIRECTORY' in '{}' file.""" .format (
1541
+ config_filename
1542
+ )
1407
1543
)
1408
- )
1409
- quit ()
1544
+ quit ()
1410
1545
1411
- cubemxdirMCU = cubemxdir / "db" / "mcu"
1412
- cubemxdirIP = cubemxdirMCU / "IP"
1413
- version_file = cubemxdir / "db" / "package.xml"
1414
- cubemx_db_version = "Unknown"
1415
- cubemx_db_release = "Unknown"
1416
- xml_file = parse (str (version_file ))
1417
- Package_item = xml_file .getElementsByTagName ("Package" )
1418
- for item in Package_item :
1419
- cubemx_db_version = item .attributes ["DBVersion" ].value
1420
- PackDescription_item = xml_file .getElementsByTagName ("PackDescription" )
1421
- for item in PackDescription_item :
1422
- cubemx_db_release = item .attributes ["Release" ].value
1423
- print ("CubeMX DB version {} release {}\n " .format (cubemx_db_version , cubemx_db_release ))
1546
+ dirMCU = cubemxdir / "db" / "mcu"
1547
+ dirIP = dirMCU / "IP"
1548
+ version_file = cubemxdir / "db" / "package.xml"
1549
+ if version_file .is_file ():
1550
+ xml_file = parse (str (version_file ))
1551
+ PackDescription_item = xml_file .getElementsByTagName ("PackDescription" )
1552
+ for item in PackDescription_item :
1553
+ db_release = item .attributes ["Release" ].value
1554
+
1555
+ # Process DB release
1556
+ release_regex = r".*(\d+.\d+.\d+)$"
1557
+ release_match = re .match (release_regex , db_release )
1558
+ if release_match :
1559
+ db_release = release_match .group (1 )
1560
+ print ("CubeMX DB release {}\n " .format (db_release ))
1424
1561
1425
1562
if args .mcu :
1426
- # check input file exists
1427
- if not ((cubemxdirMCU / args .mcu ).is_file ()):
1563
+ # Check input file exists
1564
+ if not ((dirMCU / args .mcu ).is_file ()):
1428
1565
print ("\n " + args .mcu + " file not found" )
1429
- print ("\n Check in " + cubemxdirMCU + " the correct name of this file" )
1566
+ print ("\n Check in " + dirMCU + " the correct name of this file" )
1430
1567
print ("\n You may use double quotes for file containing special characters" )
1431
1568
quit ()
1432
- mcu_list .append (cubemxdirMCU / args .mcu )
1569
+ mcu_list .append (dirMCU / args .mcu )
1433
1570
else :
1434
- mcu_list = cubemxdirMCU .glob ("STM32*.xml" )
1571
+ mcu_list = dirMCU .glob ("STM32*.xml" )
1435
1572
1436
1573
if args .list :
1437
1574
print ("Available xml files description:" )
@@ -1446,15 +1583,7 @@ def parse_pins():
1446
1583
)
1447
1584
1448
1585
for mcu_file in mcu_list :
1449
- print (
1450
- "Generating {}, {}, {} and {} for '{}'..." .format (
1451
- periph_c_filename ,
1452
- pinvar_h_filename ,
1453
- variant_cpp_filename ,
1454
- variant_h_filename ,
1455
- mcu_file .name ,
1456
- )
1457
- )
1586
+ print ("Generating files for '{}'..." .format (mcu_file .name ))
1458
1587
out_path = cur_dir / "Arduino" / mcu_file .name [:7 ] / mcu_file .stem
1459
1588
periph_c_filepath = out_path / periph_c_filename
1460
1589
periph_h_filepath = out_path / pinvar_h_filename
@@ -1478,7 +1607,7 @@ def parse_pins():
1478
1607
if gpiofile == "ERROR" :
1479
1608
print ("Could not find GPIO file" )
1480
1609
quit ()
1481
- xml_gpio = parse (str (cubemxdirIP / ("GPIO-" + gpiofile + "_Modes.xml" )))
1610
+ xml_gpio = parse (str (dirIP / ("GPIO-" + gpiofile + "_Modes.xml" )))
1482
1611
1483
1612
parse_pins ()
1484
1613
sort_my_lists ()
0 commit comments