|
@@ -72,7 +72,7 @@
|
72
|
72
|
from __future__ import print_function
|
73
|
73
|
from __future__ import division
|
74
|
74
|
|
75
|
|
-import sys,os
|
|
75
|
+import sys,os,re
|
76
|
76
|
|
77
|
77
|
pwd = os.getcwd() # make sure we're executing from the correct directory level
|
78
|
78
|
pwd = pwd.replace('\\', '/')
|
|
@@ -123,7 +123,7 @@ from datetime import datetime, date, time
|
123
|
123
|
#
|
124
|
124
|
##########################################################################################
|
125
|
125
|
|
126
|
|
-def get_answer(board_name, cpu_label_txt, cpu_a_txt, cpu_b_txt):
|
|
126
|
+def get_answer(board_name, question_txt, options, default_value=1):
|
127
|
127
|
|
128
|
128
|
if python_ver == 2:
|
129
|
129
|
import Tkinter as tk
|
|
@@ -151,10 +151,10 @@ def get_answer(board_name, cpu_label_txt, cpu_a_txt, cpu_b_txt):
|
151
|
151
|
root_get_answer.protocol("WM_DELETE_WINDOW", disable_event)
|
152
|
152
|
root_get_answer.resizable(False, False)
|
153
|
153
|
|
154
|
|
- root_get_answer.radio_state = 1 # declare variables used by TK and enable
|
|
154
|
+ root_get_answer.radio_state = default_value # declare variables used by TK and enable
|
155
|
155
|
|
156
|
156
|
global get_answer_val
|
157
|
|
- get_answer_val = 2 # return get_answer_val, set default to match radio_state default
|
|
157
|
+ get_answer_val = default_value # return get_answer_val, set default to match radio_state default
|
158
|
158
|
|
159
|
159
|
radio_state = tk.IntVar()
|
160
|
160
|
radio_state.set(get_answer_val)
|
|
@@ -162,35 +162,27 @@ def get_answer(board_name, cpu_label_txt, cpu_a_txt, cpu_b_txt):
|
162
|
162
|
l1 = tk.Label(text=board_name, fg="light green", bg="dark green",
|
163
|
163
|
font="default 14 bold").grid(row=0, columnspan=2, sticky='EW', ipadx=2, ipady=2)
|
164
|
164
|
|
165
|
|
- l2 = tk.Label(text=cpu_label_txt).grid(row=1, pady=4, columnspan=2, sticky='EW')
|
166
|
|
-
|
167
|
|
- b4 = tk.Radiobutton(
|
168
|
|
- text=cpu_a_txt,
|
169
|
|
- fg="black",
|
170
|
|
- bg="lightgray",
|
171
|
|
- relief=tk.SUNKEN,
|
172
|
|
- selectcolor="green",
|
173
|
|
- variable=radio_state,
|
174
|
|
- value=1,
|
175
|
|
- indicatoron=0,
|
176
|
|
- command=CPU_exit_3
|
177
|
|
- ).grid(row=2, pady=1, ipady=2, ipadx=10, columnspan=2)
|
178
|
|
-
|
179
|
|
- b5 = tk.Radiobutton(
|
180
|
|
- text=cpu_b_txt,
|
181
|
|
- fg="black",
|
182
|
|
- bg="lightgray",
|
183
|
|
- relief=tk.SUNKEN,
|
184
|
|
- selectcolor="green",
|
185
|
|
- variable=radio_state,
|
186
|
|
- value=2,
|
187
|
|
- indicatoron=0,
|
188
|
|
- command=CPU_exit_3
|
189
|
|
- ).grid(row=3, pady=1, ipady=2, ipadx=10, columnspan=2) # use same variable but inverted so they will track
|
190
|
|
-
|
191
|
|
- b6 = tk.Button(text="Cancel", fg="red", command=kill_session).grid(row=4, column=0, padx=4, pady=4, ipadx=2, ipady=2)
|
192
|
|
-
|
193
|
|
- b7 = tk.Button(text="Continue", fg="green", command=got_answer).grid(row=4, column=1, padx=4, pady=4, ipadx=2, ipady=2)
|
|
165
|
+ l2 = tk.Label(text=question_txt).grid(row=1, pady=4, columnspan=2, sticky='EW')
|
|
166
|
+
|
|
167
|
+ buttons = []
|
|
168
|
+
|
|
169
|
+ for index, val in enumerate(options):
|
|
170
|
+ buttons.append(
|
|
171
|
+ tk.Radiobutton(
|
|
172
|
+ text=val,
|
|
173
|
+ fg="black",
|
|
174
|
+ bg="lightgray",
|
|
175
|
+ relief=tk.SUNKEN,
|
|
176
|
+ selectcolor="green",
|
|
177
|
+ variable=radio_state,
|
|
178
|
+ value=index + 1,
|
|
179
|
+ indicatoron=0,
|
|
180
|
+ command=CPU_exit_3
|
|
181
|
+ ).grid(row=index + 2, pady=1, ipady=2, ipadx=10, columnspan=2))
|
|
182
|
+
|
|
183
|
+ b6 = tk.Button(text="Cancel", fg="red", command=kill_session).grid(row=(2 + len(options)), column=0, padx=4, pady=4, ipadx=2, ipady=2)
|
|
184
|
+
|
|
185
|
+ b7 = tk.Button(text="Continue", fg="green", command=got_answer).grid(row=(2 + len(options)), column=1, padx=4, pady=4, ipadx=2, ipady=2)
|
194
|
186
|
|
195
|
187
|
def got_answer_():
|
196
|
188
|
root_get_answer.destroy()
|
|
@@ -485,6 +477,11 @@ def get_env_from_line(line, start_position):
|
485
|
477
|
return env, next_position
|
486
|
478
|
|
487
|
479
|
|
|
480
|
+def invalid_board():
|
|
481
|
+ print('ERROR - invalid board')
|
|
482
|
+ print(board_name)
|
|
483
|
+ raise SystemExit(0) # quit if unable to find board
|
|
484
|
+
|
488
|
485
|
# scan pins.h for board name and return the environment(s) found
|
489
|
486
|
def get_starting_env(board_name_full, version):
|
490
|
487
|
# get environment starting point
|
|
@@ -496,48 +493,26 @@ def get_starting_env(board_name_full, version):
|
496
|
493
|
with open(path, 'r') as myfile:
|
497
|
494
|
pins_h = myfile.read()
|
498
|
495
|
|
499
|
|
- env_A = ''
|
500
|
|
- env_B = ''
|
501
|
|
- env_C = ''
|
502
|
|
-
|
503
|
496
|
board_name = board_name_full[6:] # only use the part after "BOARD_" since we're searching the pins.h file
|
504
|
497
|
pins_h = pins_h.split('\n')
|
505
|
|
- environment = ''
|
506
|
|
- board_line = ''
|
507
|
|
- cpu_A = ''
|
508
|
|
- cpu_B = ''
|
509
|
|
- i = 0
|
510
|
498
|
list_start_found = False
|
511
|
|
- for lines in pins_h:
|
512
|
|
- i = i + 1 # i is always one ahead of the index into pins_h
|
513
|
|
- if 0 < lines.find("Unknown MOTHERBOARD value set in Configuration.h"):
|
514
|
|
- break # no more
|
515
|
|
- if 0 < lines.find('1280'):
|
|
499
|
+ possible_envs = None
|
|
500
|
+ for i, line in enumerate(pins_h):
|
|
501
|
+ if 0 < line.find("Unknown MOTHERBOARD value set in Configuration.h"):
|
|
502
|
+ invalid_board();
|
|
503
|
+ if list_start_found == False and 0 < line.find('1280'):
|
516
|
504
|
list_start_found = True
|
517
|
|
- if list_start_found == False: # skip lines until find start of CPU list
|
|
505
|
+ elif list_start_found == False: # skip lines until find start of CPU list
|
518
|
506
|
continue
|
519
|
|
- board = lines.find(board_name)
|
520
|
|
- comment_start = lines.find('// ')
|
521
|
|
- cpu_A_loc = comment_start
|
522
|
|
- cpu_B_loc = 0
|
523
|
|
- if board > 0: # need to look at the next line for environment info
|
524
|
|
- cpu_line = pins_h[i]
|
525
|
|
- comment_start = cpu_line.find('// ')
|
526
|
|
- env_A, next_position = get_env_from_line(cpu_line, comment_start) # get name of environment & start of search for next
|
527
|
|
- env_B, next_position = get_env_from_line(cpu_line, next_position) # get next environment, if it exists
|
528
|
|
- env_C, next_position = get_env_from_line(cpu_line, next_position) # get next environment, if it exists
|
529
|
|
- break
|
530
|
|
- return env_A, env_B, env_C
|
531
|
|
-
|
532
|
507
|
|
533
|
|
-# Scan input string for CPUs that users may need to select from
|
534
|
|
-# return: CPU name
|
535
|
|
-def get_CPU_name(environment):
|
536
|
|
- CPU_list = ('1280', '2560', '644', '1284', 'LPC1768', 'DUE')
|
537
|
|
- CPU_name = ''
|
538
|
|
- for CPU in CPU_list:
|
539
|
|
- if 0 < environment.find(CPU):
|
540
|
|
- return CPU
|
|
508
|
+ # Use a regex to find the board. Make sure it is surrounded by separators so the full boardname
|
|
509
|
+ # will be matched, even if multiple exist in a single MB macro. This avoids problems with boards
|
|
510
|
+ # such as MALYAN_M200 and MALYAN_M200_V2 where one board is a substring of the other.
|
|
511
|
+ if re.search(r'MB.*[\(, ]' + board_name + r'[, \)]', line):
|
|
512
|
+ # need to look at the next line for environment info
|
|
513
|
+ possible_envs = re.findall(r'env:([^ ]+)', pins_h[i + 1])
|
|
514
|
+ break
|
|
515
|
+ return possible_envs
|
541
|
516
|
|
542
|
517
|
|
543
|
518
|
# get environment to be used for the build
|
|
@@ -549,71 +524,81 @@ def get_env(board_name, ver_Marlin):
|
549
|
524
|
print(board_name)
|
550
|
525
|
raise SystemExit(0) # no environment so quit
|
551
|
526
|
|
552
|
|
- def invalid_board():
|
553
|
|
- print('ERROR - invalid board')
|
554
|
|
- print(board_name)
|
555
|
|
- raise SystemExit(0) # quit if unable to find board
|
|
527
|
+ possible_envs = get_starting_env(board_name, ver_Marlin)
|
556
|
528
|
|
557
|
|
- CPU_question = (('1280', '2560', '1280 or 2560 CPU?'), ('644', '1284', '644 or 1284 CPU?'))
|
|
529
|
+ if not possible_envs:
|
|
530
|
+ no_environment()
|
558
|
531
|
|
559
|
|
- if 0 < board_name.find('MELZI'):
|
560
|
|
- get_answer(
|
561
|
|
- board_name, " Which flavor of Melzi? ", "Melzi (Optiboot bootloader)", "Melzi "
|
562
|
|
- )
|
|
532
|
+ # Proceed to ask questions based on the available environments to filter down to a smaller list.
|
|
533
|
+ # If more then one remains after this filtering the user will be prompted to choose between
|
|
534
|
+ # all remaining options.
|
|
535
|
+
|
|
536
|
+ # Filter selection based on CPU choice
|
|
537
|
+ CPU_questions = [
|
|
538
|
+ {'options':['1280', '2560'], 'text':'1280 or 2560 CPU?', 'default':2},
|
|
539
|
+ {'options':['644', '1284'], 'text':'644 or 1284 CPU?', 'default':2},
|
|
540
|
+ {'options':['STM32F103RC', 'STM32F103RE'], 'text':'MCU Type?', 'default':1}]
|
|
541
|
+
|
|
542
|
+ for question in CPU_questions:
|
|
543
|
+ if any(question['options'][0] in env for env in possible_envs) and any(question['options'][1] in env for env in possible_envs):
|
|
544
|
+ get_answer(board_name, question['text'], [question['options'][0], question['options'][1]], question['default'])
|
|
545
|
+ possible_envs = [env for env in possible_envs if question['options'][get_answer_val - 1] in env]
|
|
546
|
+
|
|
547
|
+ # Choose which STM32 framework to use, if both are available
|
|
548
|
+ if [env for env in possible_envs if '_maple' in env] and [env for env in possible_envs if '_maple' not in env]:
|
|
549
|
+ get_answer(board_name, 'Which STM32 Framework should be used?', ['ST STM32 (Preferred)', 'Maple (Deprecated)'])
|
563
|
550
|
if 1 == get_answer_val:
|
564
|
|
- target_env = 'melzi_optiboot'
|
|
551
|
+ possible_envs = [env for env in possible_envs if '_maple' not in env]
|
565
|
552
|
else:
|
566
|
|
- target_env = 'melzi'
|
567
|
|
- else:
|
568
|
|
- env_A, env_B, env_C = get_starting_env(board_name, ver_Marlin)
|
|
553
|
+ possible_envs = [env for env in possible_envs if '_maple' in env]
|
569
|
554
|
|
570
|
|
- if env_A == '':
|
571
|
|
- no_environment()
|
572
|
|
- if env_B == '':
|
573
|
|
- return env_A # only one environment so finished
|
|
555
|
+ # Both USB and non-USB STM32 options exist, filter based on these
|
|
556
|
+ if any('STM32F103R' in env for env in possible_envs) and any('_USB' in env for env in possible_envs) and any('_USB' not in env for env in possible_envs):
|
|
557
|
+ get_answer(board_name, 'USB Support?', ['USB', 'No USB'])
|
|
558
|
+ if 1 == get_answer_val:
|
|
559
|
+ possible_envs = [env for env in possible_envs if '_USB' in env]
|
|
560
|
+ else:
|
|
561
|
+ possible_envs = [env for env in possible_envs if '_USB' not in env]
|
574
|
562
|
|
575
|
|
- CPU_A = get_CPU_name(env_A)
|
576
|
|
- CPU_B = get_CPU_name(env_B)
|
|
563
|
+ if not possible_envs:
|
|
564
|
+ no_environment()
|
|
565
|
+ if len(possible_envs) == 1:
|
|
566
|
+ return possible_envs[0] # only one environment so finished
|
577
|
567
|
|
578
|
|
- for item in CPU_question:
|
579
|
|
- if CPU_A == item[0]:
|
580
|
|
- get_answer(board_name, item[2], item[0], item[1])
|
581
|
|
- if 2 == get_answer_val:
|
582
|
|
- target_env = env_B
|
583
|
|
- else:
|
584
|
|
- target_env = env_A
|
585
|
|
- return target_env
|
|
568
|
+ target_env = None
|
586
|
569
|
|
587
|
|
- if env_A == 'LPC1768':
|
588
|
|
- if build_type == 'traceback' or (build_type == 'clean' and get_build_last() == 'LPC1768_debug_and_upload'):
|
589
|
|
- target_env = 'LPC1768_debug_and_upload'
|
590
|
|
- else:
|
591
|
|
- target_env = 'LPC1768'
|
592
|
|
- elif env_A == 'DUE':
|
593
|
|
- target_env = 'DUE'
|
594
|
|
- if build_type == 'traceback' or (build_type == 'clean' and get_build_last() == 'DUE_debug'):
|
595
|
|
- target_env = 'DUE_debug'
|
596
|
|
- elif env_B == 'DUE_USB':
|
597
|
|
- get_answer(board_name, 'DUE Download Port?', '(Native) USB port', 'Programming port')
|
598
|
|
- if 1 == get_answer_val:
|
599
|
|
- target_env = 'DUE_USB'
|
600
|
|
- else:
|
601
|
|
- target_env = 'DUE'
|
602
|
|
- elif env_A == 'STM32F103RC_btt' or env_A == 'STM32F103RE_btt':
|
603
|
|
- if env_A == 'STM32F103RE_btt':
|
604
|
|
- get_answer(board_name, 'MCU Type?', 'STM32F103RC', 'STM32F103RE')
|
605
|
|
- if 1 == get_answer_val:
|
606
|
|
- env_A = 'STM32F103RC_btt'
|
607
|
|
- target_env = env_A
|
608
|
|
- if env_A == 'STM32F103RC_btt':
|
609
|
|
- get_answer(board_name, 'RCT6 Flash Size?', '512K', '256K')
|
610
|
|
- if 1 == get_answer_val:
|
611
|
|
- target_env += '_512K'
|
612
|
|
- get_answer(board_name, 'USB Support?', 'USB', 'No USB')
|
613
|
|
- if 1 == get_answer_val:
|
614
|
|
- target_env += '_USB'
|
|
570
|
+ # A few environments require special behavior
|
|
571
|
+ if 'LPC1768' in possible_envs:
|
|
572
|
+ if build_type == 'traceback' or (build_type == 'clean' and get_build_last() == 'LPC1768_debug_and_upload'):
|
|
573
|
+ target_env = 'LPC1768_debug_and_upload'
|
615
|
574
|
else:
|
616
|
|
- invalid_board()
|
|
575
|
+ target_env = 'LPC1768'
|
|
576
|
+ elif 'DUE' in possible_envs:
|
|
577
|
+ target_env = 'DUE'
|
|
578
|
+ if build_type == 'traceback' or (build_type == 'clean' and get_build_last() == 'DUE_debug'):
|
|
579
|
+ target_env = 'DUE_debug'
|
|
580
|
+ elif 'DUE_USB' in possible_envs:
|
|
581
|
+ get_answer(board_name, 'DUE Download Port?', ['(Native) USB port', 'Programming port'])
|
|
582
|
+ if 1 == get_answer_val:
|
|
583
|
+ target_env = 'DUE_USB'
|
|
584
|
+ else:
|
|
585
|
+ target_env = 'DUE'
|
|
586
|
+ else:
|
|
587
|
+ options = possible_envs
|
|
588
|
+ # Perform some substitutions for environment names which follow a consistent
|
|
589
|
+ # naming pattern and are very commonly used. This is fragile code, and replacements
|
|
590
|
+ # should only be made here for stable environments unlikely to change often.
|
|
591
|
+ for i, option in enumerate(options):
|
|
592
|
+ if 'melzi' in option:
|
|
593
|
+ options[i] = 'Melzi'
|
|
594
|
+ elif 'sanguino1284p' in option:
|
|
595
|
+ options[i] = 'sanguino1284p'
|
|
596
|
+ if 'optiboot' in option:
|
|
597
|
+ options[i] = options[i] + ' (Optiboot Bootloader)'
|
|
598
|
+ if 'optimized' in option:
|
|
599
|
+ options[i] = options[i] + ' (Optimized for Size)'
|
|
600
|
+ get_answer(board_name, 'Which environment?', options)
|
|
601
|
+ target_env = possible_envs[get_answer_val - 1]
|
617
|
602
|
|
618
|
603
|
if build_type == 'traceback' and target_env != 'LPC1768_debug_and_upload' and target_env != 'DUE_debug' and Marlin_ver == 2:
|
619
|
604
|
print("ERROR - this board isn't setup for traceback")
|