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