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