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