Browse Source

add AT90USB support & add items to popup menu (#10779)

Bob Kuhn 6 years ago
parent
commit
62e2987488

+ 8
- 8
Marlin/src/pins/pins.h View File

@@ -252,21 +252,21 @@
252 252
 //
253 253
 
254 254
 #elif MB(TEENSYLU)
255
-  #include "pins_TEENSYLU.h"          // AT90USB1286, AT90USB1286P                  env:teensy20
255
+  #include "pins_TEENSYLU.h"          // AT90USB1286, AT90USB1286P                  env:at90USB1286_CDC
256 256
 #elif MB(PRINTRBOARD)
257
-  #include "pins_PRINTRBOARD.h"       // AT90USB1286                                env:teensy20
257
+  #include "pins_PRINTRBOARD.h"       // AT90USB1286                                env:at90USB1286_DFU
258 258
 #elif MB(PRINTRBOARD_REVF)
259
-  #include "pins_PRINTRBOARD_REVF.h"  // AT90USB1286                                env:teensy20
259
+  #include "pins_PRINTRBOARD_REVF.h"  // AT90USB1286                                env:at90USB1286_DFU
260 260
 #elif MB(BRAINWAVE)
261
-  #include "pins_BRAINWAVE.h"         // AT90USB646                                 env:teensy20
261
+  #include "pins_BRAINWAVE.h"         // AT90USB646                                 env:at90USB1286_CDC
262 262
 #elif MB(BRAINWAVE_PRO)
263
-  #include "pins_BRAINWAVE_PRO.h"     // AT90USB1286                                env:teensy20
263
+  #include "pins_BRAINWAVE_PRO.h"     // AT90USB1286                                env:at90USB1286_CDC
264 264
 #elif MB(SAV_MKI)
265
-  #include "pins_SAV_MKI.h"           // AT90USB1286                                env:teensy20
265
+  #include "pins_SAV_MKI.h"           // AT90USB1286                                env:at90USB1286_CDC
266 266
 #elif MB(TEENSY2)
267 267
   #include "pins_TEENSY2.h"           // AT90USB1286                                env:teensy20
268 268
 #elif MB(5DPRINT)
269
-  #include "pins_5DPRINT.h"           // AT90USB1286                                env:teensy20
269
+  #include "pins_5DPRINT.h"           // AT90USB1286                                ?env:at90USB1286_DFU
270 270
 
271 271
 //
272 272
 // Re-ARM - LPC1768
@@ -342,7 +342,7 @@
342 342
 #elif MB(STM3R_MINI)
343 343
   #include "pins_STM3R_MINI.h"        // STM32F1                                    env:STM32F1
344 344
 #elif MB(MALYAN_M200)
345
-  #include "pins_MALYAN_M200.h"       // STM32F1                                    env:STM32F1
345
+  #include "pins_MALYAN_M200.h"       // STM32F1                                    env:malyanm200
346 346
 #elif MB(BEAST)
347 347
   #include "pins_BEAST.h"             // STM32F4                                    env:STM32F1
348 348
 #elif MB(CHITU3D)

+ 20
- 0
buildroot/share/PlatformIO/boards/at90USB1286.json View File

@@ -0,0 +1,20 @@
1
+{
2
+  "build": {
3
+    "core": "teensy",
4
+    "extra_flags": "-DTEENSY2PP",
5
+    "f_cpu": "16000000L",
6
+    "mcu": "at90usb1286"
7
+  },
8
+  "frameworks": [
9
+    "arduino"
10
+  ],
11
+  "name": "at90USB1286.json",
12
+  "upload": {
13
+    "maximum_ram_size": 8192,
14
+    "maximum_size": 130048,
15
+    "require_upload_port": true,
16
+    "protocol": ""
17
+  },
18
+  "url": "https://github.com/MarlinFirmware/Marlin",
19
+  "vendor": "various"
20
+}

+ 370
- 87
buildroot/share/atom/auto_build.py View File

@@ -89,6 +89,13 @@ else:
89 89
   print "This script only runs under python 2"
90 90
   exit()
91 91
 
92
+import platform
93
+current_OS = platform.system()
94
+
95
+#globals
96
+target_env = ''
97
+board_name = ''
98
+
92 99
 #########
93 100
 #  Python 2 error messages:
94 101
 #    Can't find a usable init.tcl in the following directories ...
@@ -101,10 +108,6 @@ else:
101 108
 #    reboot
102 109
 #########
103 110
 
104
-#globals
105
-target_env = ''
106
-board_name = ''
107
-
108 111
 
109 112
 
110 113
 ##########################################################################################
@@ -191,28 +194,226 @@ def get_answer(board_name, cpu_label_txt, cpu_a_txt, cpu_b_txt):
191 194
 # end - get answer
192 195
 
193 196
 
197
+#
198
+# move custom board definitions from project folder to PlatformIO
199
+#
200
+def resolve_path(path):
201
+        import os
202
+
203
+    # turn the selection into a partial path
204
+       #get line and column numbers
205
+        line_num = 1
206
+        column_num = 1
207
+        line_start = path.find(':')
208
+        column_start = path.find(':', line_start + 1)
209
+        if column_start == -1:
210
+          column_start = len(path)
211
+        column_end = path.find(':', column_start + 1)
212
+        if column_end == -1:
213
+          column_end = len(path)
214
+        if 0 <= line_start:
215
+          line_num = path[ line_start + 1 : column_start]
216
+          if line_num == '':
217
+            line_num = 1
218
+        if not(column_start == column_end):
219
+          column_num = path[ column_start + 1 : column_end]
220
+          if column_num == '':
221
+            column_num = 1
222
+
223
+
224
+        path = path[ : path.find(':')]  # delete the line number and anything after
225
+        path = path.replace('\\','/')
226
+
227
+      # resolve as many '../' as we can
228
+        while 0 <= path.find('../'):
229
+          end =  path.find('../') - 1
230
+          start = path.find('/')
231
+          while 0 <= path.find('/',start) and end > path.find('/',start):
232
+            start = path.find('/',start) + 1
233
+          path = path[0:start] + path[end + 4: ]
234
+
235
+        # this is an alternative to the above - it just deletes the '../' section
236
+        # start_temp = path.find('../')
237
+        # while 0 <= path.find('../',start_temp):
238
+        #   start = path.find('../',start_temp)
239
+        #   start_temp = start  + 1
240
+        # if 0 <= start:
241
+        #   path = path[start + 2 : ]
242
+
243
+
244
+        start = path.find('/')
245
+        if not(0 == start):            # make sure path starts with '/'
246
+          while 0 == path.find(' '):    # eat any spaces at the beginning
247
+            path = path[ 1 : ]
248
+          path = '/' + path
249
+
250
+        if current_OS == 'Windows':
251
+          search_path = path.replace('/', '\\')  # os.walk uses '\' in Windows
252
+        else:
253
+          search_path = path
254
+
255
+        start_path = os.path.abspath('')
256
+
257
+    # search project directory for the selection
258
+        found = False
259
+        full_path = ''
260
+        for root, directories, filenames in os.walk(start_path):
261
+          for filename in filenames:
262
+                  if  0 <= root.find('.git'):              # don't bother looking in this directory
263
+                    break
264
+                  full_path = os.path.join(root,filename)
265
+                  if 0 <= full_path.find(search_path):
266
+                    found = True
267
+                    break
268
+          if found:
269
+            break
270
+
271
+        return full_path, line_num, column_num
272
+
273
+# end - resolve_path
274
+
275
+
276
+#
277
+# Opens the file in the preferred editor at the line & column number
278
+#   If the preferred editor isn't already running then it tries the next.
279
+#   If none are open then the system default is used.
280
+#
281
+# Editor order:
282
+#   1. Notepad++  (Windows only)
283
+#   2. Sublime Text
284
+#   3. Atom
285
+#   4. System default (opens at line 1, column 1 only)
286
+#
287
+def open_file(path):
288
+        import subprocess
289
+        file_path, line_num, column_num = resolve_path(path)
290
+
291
+        if file_path == '' :
292
+          return
293
+
294
+        if current_OS == 'Windows':
295
+
296
+            editor_note = subprocess.check_output('wmic process where "name=' + "'notepad++.exe'" + '" get ExecutablePath')
297
+            editor_sublime = subprocess.check_output('wmic process where "name=' + "'sublime_text.exe'" + '" get ExecutablePath')
298
+            editor_atom = subprocess.check_output('wmic process where "name=' + "'atom.exe'" + '" get ExecutablePath')
299
+
300
+            if 0 <= editor_note.find('notepad++.exe'):
301
+                start = editor_note.find('\n') + 1
302
+                end = editor_note.find('\n',start + 5) -4
303
+                editor_note = editor_note[ start : end]
304
+                command = file_path ,  ' -n' + str(line_num) ,   ' -c' + str(column_num)
305
+                subprocess.Popen([editor_note, command])
306
+
307
+            elif 0 <= editor_sublime.find('sublime_text.exe'):
308
+                start = editor_sublime.find('\n') + 1
309
+                end = editor_sublime.find('\n',start + 5) -4
310
+                editor_sublime = editor_sublime[ start : end]
311
+                command = file_path + ':' + line_num + ':' + column_num
312
+                subprocess.Popen([editor_sublime, command])
313
+
314
+            elif 0 <= editor_atom.find('atom.exe'):
315
+                start = editor_atom.find('\n') + 1
316
+                end = editor_atom.find('\n',start + 5) -4
317
+                editor_atom = editor_atom[ start : end]
318
+                command = file_path  + ':' + str(line_num) + ':' + str(column_num)
319
+                subprocess.Popen([editor_atom, command])
320
+
321
+            else:
322
+              os.startfile(resolve_path(path))  # open file with default app
323
+
324
+        elif current_OS == 'Linux':
325
+
326
+              command = file_path  + ':' + str(line_num) + ':' + str(column_num)
327
+              running_apps = subprocess.Popen('ps ax -o cmd', stdout=subprocess.PIPE, shell=True)
328
+              (output, err) = running_apps.communicate()
329
+              temp = output.split('\n')
330
+
331
+              def find_editor_linux(name, search_obj):
332
+                  for line in search_obj:
333
+                      if 0 <= line.find(name):
334
+                          path = line
335
+                          return True, path
336
+                  return False , ''
337
+
338
+              (success_sublime, editor_path_sublime) = find_editor_linux('sublime_text',temp)
339
+              (success_atom, editor_path_atom) = find_editor+linux('atom',temp)
340
+
341
+              if success_sublime:
342
+                  subprocess.Popen([editor_path_sublime, command])
343
+
344
+              elif success_atom:
345
+                  subprocess.Popen([editor_path_atom, command])
346
+
347
+              else:
348
+                  os.system('xdg-open ' + file_path )
349
+
350
+        elif current_OS == 'Darwin':  # MAC
351
+
352
+              command = file_path  + ':' + str(line_num) + ':' + str(column_num)
353
+              running_apps = subprocess.Popen('ps axwww -o command', stdout=subprocess.PIPE, shell=True)
354
+              (output, err) = running_apps.communicate()
355
+              temp = output.split('\n')
356
+
357
+              def find_editor_mac(name, search_obj):
358
+                  for line in search_obj:
359
+                      if 0 <= line.find(name):
360
+                          path = line
361
+                          if 0 <= path.find('-psn'):
362
+                              path = path[ : path.find('-psn') - 1 ]
363
+                          return True, path
364
+                  return False , ''
365
+
366
+              (success_sublime, editor_path_sublime) = find_editor_mac('Sublime',temp)
367
+              (success_atom, editor_path_atom) = find_editor_mac('Atom',temp)
368
+
369
+              if success_sublime:
370
+                  subprocess.Popen([editor_path_sublime, command])
371
+
372
+              elif success_atom:
373
+                  subprocess.Popen([editor_path_atom, command])
374
+
375
+              else:
376
+                  os.system('open ' + file_path )
377
+# end - open_file
378
+
379
+
380
+#
381
+# move custom board definitions from project folder to PlatformIO
382
+#
383
+def copy_boards_dir():
384
+
385
+        temp = os.environ
386
+        for key in temp:
387
+          if 0 <=  os.environ[key].find('.platformio'):
388
+            part = os.environ[key].split(';')
389
+            for part2 in part:
390
+              if 0 <=  part2.find('.platformio'):
391
+                path = part2
392
+                break
393
+
394
+        PIO_path = path[ : path.find('.platformio') + 11]
395
+
396
+#         import sys
397
+#         import subprocess
398
+#         pio_subprocess = subprocess.Popen(['platformio', 'run', '-t', 'envdump'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
399
+#
400
+#         # stream output from subprocess and split it into lines
401
+#         for line in iter(pio_subprocess.stdout.readline, ''):
402
+#             if 0 <= line.find('PIOHOME_DIR'):
403
+#               start = line.find(':') + 3
404
+#               end =  line.find(',') - 1
405
+#               PIO_path = line[start:end]
406
+
407
+
408
+        PIO_path =  PIO_path.replace("\\", "/")
409
+        PIO_path =  PIO_path.replace("//", "/") + '/boards'
410
+
411
+        board_path = 'buildroot/share/PlatformIO/boards'
194 412
 
195
-def env_name_check(argument):
196
-      name_check = {
197
-        'teensy35'                   :  True,
198
-        'teensy20'                   :  True,
199
-        'STM32F4'                    :  True,
200
-        'STM32F1'                    :  True,
201
-        'sanguino_atmega644p'        :  True,
202
-        'sanguino_atmega1284p'       :  True,
203
-        'rambo'                      :  True,
204
-        'melzi_optiboot'             :  True,
205
-        'melzi'                      :  True,
206
-        'megaatmega2560'             :  True,
207
-        'megaatmega1280'             :  True,
208
-        'malyanm200'                 :  True,
209
-        'LPC1768'                    :  True,
210
-        'DUE_debug'                  :  True,
211
-        'DUE_USB'                    :  True,
212
-        'DUE'                        :  True
213
-      }
413
+        from distutils.dir_util import copy_tree
414
+        copy_tree(board_path, PIO_path)
214 415
 
215
-      return name_check.get(argument, False)
416
+# end copy_boards_dir
216 417
 
217 418
 
218 419
 # gets the last build environment
@@ -223,14 +424,13 @@ def get_build_last():
223 424
         date_last = 0.0
224 425
         DIR__pioenvs = os.listdir('.pioenvs')
225 426
         for name in DIR__pioenvs:
226
-          if env_name_check(name):
227
-            DIR_temp = os.listdir('.pioenvs/' + name)
228
-            for names_temp in DIR_temp:
229
-              if 0 == names_temp.find('firmware.'):
230
-                date_temp = os.path.getmtime('.pioenvs/' + name + '/' + names_temp)
231
-                if date_temp > date_last:
232
-                  date_last = date_temp
233
-                  env_last = name
427
+          DIR_temp = os.listdir('.pioenvs/' + name)
428
+          for names_temp in DIR_temp:
429
+            if 0 == names_temp.find('firmware.'):
430
+              date_temp = os.path.getmtime('.pioenvs/' + name + '/' + names_temp)
431
+              if date_temp > date_last:
432
+                date_last = date_temp
433
+                env_last = name
234 434
       return env_last
235 435
 
236 436
 
@@ -296,6 +496,10 @@ def get_starting_env(board_name_full, version):
296 496
       with open(path, 'r') as myfile:
297 497
         pins_h = myfile.read()
298 498
 
499
+      env_A = ''
500
+      env_B = ''
501
+      env_C = ''
502
+
299 503
       board_name = board_name_full[ 6 : ]  # only use the part after "BOARD_" since we're searching the pins.h file
300 504
       pins_h = pins_h.split('\n')
301 505
       environment = ''
@@ -350,10 +554,10 @@ def get_env(board_name, ver_Marlin):
350 554
             raise SystemExit(0)                          # quit if unable to find board
351 555
 
352 556
 
353
-      CPU_question = ( ('1280', '2560', "1280 or 2560 CPU?"), ('644', '1284', "644 or 1284 CPU?") )
557
+      CPU_question = ( ('1280', '2560', " 1280 or 2560 CPU? "), ('644', '1284', " 644 or 1284 CPU? ") )
354 558
 
355 559
       if 0 < board_name.find('MELZI') :
356
-          get_answer(board_name, "Which flavor of Melzi?", "Melzi (Optiboot bootloader)", "Melzi                                      ")
560
+          get_answer(' ' + board_name + ' ', " Which flavor of Melzi? ", "Melzi (Optiboot bootloader)", "Melzi                                      ")
357 561
           if 1 == get_answer_val:
358 562
             target_env = 'melzi_optiboot'
359 563
           else:
@@ -371,7 +575,7 @@ def get_env(board_name, ver_Marlin):
371 575
 
372 576
           for item in CPU_question:
373 577
             if CPU_A == item[0]:
374
-              get_answer(board_name, item[2], item[0], item[1])
578
+              get_answer(' ' + board_name + ' ', item[2], item[0], item[1])
375 579
               if 2 == get_answer_val:
376 580
                 target_env = env_B
377 581
               else:
@@ -388,7 +592,7 @@ def get_env(board_name, ver_Marlin):
388 592
               if build_type == 'traceback' or (build_type == 'clean' and get_build_last() == 'DUE_debug'):
389 593
                   target_env = 'DUE_debug'
390 594
               elif env_B == 'DUE_USB':
391
-                get_answer(board_name, "DUE: need download port", "USB (native USB) port", "Programming port       ")
595
+                get_answer(' ' + board_name + ' ', " DUE: need download port ", "USB (native USB) port", "Programming port       ")
392 596
                 if 1 == get_answer_val:
393 597
                   target_env = 'DUE_USB'
394 598
                 else:
@@ -408,6 +612,7 @@ def get_env(board_name, ver_Marlin):
408 612
 # puts screen text into queue so that the parent thread can fetch the data from this thread
409 613
 import Queue
410 614
 IO_queue = Queue.Queue()
615
+PIO_queue = Queue.Queue()
411 616
 def write_to_screen_queue(text, format_tag = 'normal'):
412 617
       double_in = [text, format_tag]
413 618
       IO_queue.put(double_in, block = False)
@@ -431,6 +636,7 @@ standard = True
431 636
 prev_line_COM = False
432 637
 next_line_warning = False
433 638
 warning_continue = False
639
+line_counter = 0
434 640
 
435 641
 def line_print(line_input):
436 642
 
@@ -441,6 +647,7 @@ def line_print(line_input):
441 647
       global prev_line_COM
442 648
       global next_line_warning
443 649
       global warning_continue
650
+      global line_counter
444 651
 
445 652
 
446 653
 
@@ -490,12 +697,19 @@ def line_print(line_input):
490 697
               write_to_screen_queue(text[found_right :                ] + '\n')
491 698
             break
492 699
         if did_something == False:
493
-          write_to_screen_queue(text + '\n')
700
+          r_loc = text.find('\r') + 1
701
+          if r_loc > 0 and r_loc < len(text):  # need to split this line
702
+            text = text.split('\r')
703
+            for line in text:
704
+              write_to_screen_queue(line + '\n')
705
+          else:
706
+            write_to_screen_queue(text + '\n')
494 707
       # end - write_to_screen_with_replace
495 708
 
496 709
 
497 710
 
498 711
     # scan the line
712
+      line_counter = line_counter + 1
499 713
       max_search = len(line_input)
500 714
       if max_search > 3 :
501 715
         max_search = 3
@@ -510,7 +724,14 @@ def line_print(line_input):
510 724
         prev_line_COM = False
511 725
         prev_line_COM = False
512 726
         warning_continue = True
513
-      if beginning == 'War' or \
727
+      if 0 < line_input.find('Thank you') or 0 < line_input.find('SUMMARY') :
728
+        warning = False               #standard line found
729
+        warning_FROM = False
730
+        error = False
731
+        standard = True
732
+        prev_line_COM = False
733
+        warning_continue = False
734
+      elif beginning == 'War' or \
514 735
         beginning == '#er' or \
515 736
         beginning == 'In ' or \
516 737
         (beginning != 'Com' and prev_line_COM == True and not(beginning == 'Arc' or beginning == 'Lin'  or beginning == 'Ind') or \
@@ -539,11 +760,6 @@ def line_print(line_input):
539 760
         error = True
540 761
         standard = False
541 762
         prev_line_COM = False
542
-
543
-      elif beginning == 'fro' and warning == True :  # start of warning /error block
544
-        warning_FROM = True
545
-        prev_line_COM = False
546
-        warning_continue = True
547 763
       elif 0 < line_input.find(': error:') or \
548 764
         0 < line_input.find(': fatal error:'):       # start of warning /error block
549 765
         warning = False                                 # error found
@@ -552,9 +768,14 @@ def line_print(line_input):
552 768
         standard = False
553 769
         prev_line_COM = False
554 770
         warning_continue = True
771
+      elif beginning == 'fro' and warning == True or \
772
+        beginning == '.pi' :                             # start of warning /error block
773
+        warning_FROM = True
774
+        prev_line_COM = False
775
+        warning_continue = True
555 776
       elif warning_continue == True:
556 777
         warning = True
557
-        warning_FROM = False          # keep the warning status going until find a standard line
778
+        warning_FROM = False          # keep the warning status going until find a standard line or an error
558 779
         error = False
559 780
         standard = False
560 781
         prev_line_COM = False
@@ -608,6 +829,7 @@ def run_PIO(dummy):
608 829
 
609 830
     import subprocess
610 831
     import sys
832
+
611 833
     print 'starting platformio'
612 834
 
613 835
     if   build_type == 'build':
@@ -664,7 +886,7 @@ def run_PIO(dummy):
664 886
 
665 887
   # stream output from subprocess and split it into lines
666 888
     for line in iter(pio_subprocess.stdout.readline, ''):
667
-        line_print(line.replace('\n', ''))
889
+          line_print(line.replace('\n', ''))
668 890
 
669 891
 
670 892
   # append info used to run PlatformIO
@@ -696,10 +918,16 @@ import tkFileDialog
696 918
 
697 919
 
698 920
 class output_window(Text):
699
-
921
+ # based on Super Text
700 922
     global continue_updates
701 923
     continue_updates = True
702 924
 
925
+    global search_position
926
+    search_position = ''       # start with invalid search position
927
+
928
+    global error_found
929
+    error_found = False        # are there any errors?
930
+
703 931
 
704 932
     def  __init__(self):
705 933
 
@@ -714,6 +942,7 @@ class output_window(Text):
714 942
         self.config(tabs=(400,))  # configure Text widget tab stops
715 943
         self.config(background = 'black', foreground = 'white', font= ("consolas", 12), wrap = 'word', undo = 'True')
716 944
         self.config(height  = 24, width = 120)
945
+        self.config(insertbackground = 'pale green')  # keyboard insertion point
717 946
         self.pack(side='left', fill='both', expand=True)
718 947
 
719 948
         self.tag_config('normal', foreground = 'white')
@@ -721,8 +950,12 @@ class output_window(Text):
721 950
         self.tag_config('error', foreground = 'red')
722 951
         self.tag_config('highlight_green', foreground = 'green')
723 952
         self.tag_config('highlight_blue', foreground = 'cyan')
953
+        self.tag_config('error_highlight_inactive', background = 'dim gray')
954
+        self.tag_config('error_highlight_active', background = 'light grey')
724 955
 
725
-#        self.bind('<Control-Key-a>', self.select_all)  # the event happens but the action doesn't
956
+        self.bind_class("Text","<Control-a>", self.select_all)  # required in windows, works in others
957
+        self.bind_all("<Control-Shift-E>", self.scroll_errors)
958
+        self.bind_class("<Control-Shift-R>", self.rebuild)
726 959
 
727 960
         # scrollbar
728 961
 
@@ -733,15 +966,28 @@ class output_window(Text):
733 966
 
734 967
         # pop-up menu
735 968
         self.popup = tk.Menu(self, tearoff=0)
736
-        self.popup.add_command(label='Cut', command=self._cut)
969
+
737 970
         self.popup.add_command(label='Copy', command=self._copy)
738 971
         self.popup.add_command(label='Paste', command=self._paste)
739 972
         self.popup.add_separator()
973
+        self.popup.add_command(label='Cut', command=self._cut)
974
+        self.popup.add_separator()
740 975
         self.popup.add_command(label='Select All', command=self._select_all)
741 976
         self.popup.add_command(label='Clear All', command=self._clear_all)
742 977
         self.popup.add_separator()
743 978
         self.popup.add_command(label='Save As', command=self._file_save_as)
744
-        self.bind('<Button-3>', self._show_popup)
979
+        self.popup.add_separator()
980
+ #       self.popup.add_command(label='Repeat Build(CTL-shift-r)', command=self._rebuild)
981
+        self.popup.add_command(label='Repeat Build', command=self._rebuild)
982
+        self.popup.add_separator()
983
+        self.popup.add_command(label='Scroll Errors (CTL-shift-e)', command=self._scroll_errors)
984
+        self.popup.add_separator()
985
+        self.popup.add_command(label='Open File at Cursor', command=self._open_selected_file)
986
+
987
+        if current_OS == 'Darwin':  # MAC
988
+          self.bind('<Button-2>', self._show_popup)  # macOS only
989
+        else:
990
+          self.bind('<Button-3>', self._show_popup)  # Windows & Linux
745 991
 
746 992
 
747 993
   # threading & subprocess section
@@ -761,18 +1007,17 @@ class output_window(Text):
761 1007
     def check_thread(self):  # wait for user to kill the window
762 1008
         global continue_updates
763 1009
         if continue_updates == True:
764
-          self.root.after(20, self.check_thread)
1010
+          self.root.after(10, self.check_thread)
765 1011
 
766 1012
 
767 1013
     def update(self):
768 1014
         global continue_updates
769 1015
         if continue_updates == True:
770
-           self.root.after(20, self.update)#method is called every 50ms
1016
+           self.root.after(10, self.update)#method is called every 50ms
771 1017
         temp_text = ['0','0']
772 1018
         if IO_queue.empty():
773 1019
           if not(self.secondary_thread.is_alive()):
774 1020
             continue_updates = False  # queue is exhausted and thread is dead so no need for further updates
775
-            self.tag_add('sel', '1.0', 'end')
776 1021
         else:
777 1022
           try:
778 1023
               temp_text = IO_queue.get(block = False)
@@ -785,6 +1030,74 @@ class output_window(Text):
785 1030
 
786 1031
   # text editing section
787 1032
 
1033
+
1034
+    def _scroll_errors(self):
1035
+        global search_position
1036
+        global error_found
1037
+        if search_position == '':  # first time so highlight all errors
1038
+            countVar = tk.IntVar()
1039
+            search_position = '1.0'
1040
+            search_count = 0
1041
+            while not(search_position == '') and search_count < 100:
1042
+                search_position = self.search("error", search_position, stopindex="end", count=countVar, nocase=1)
1043
+                search_count = search_count + 1
1044
+                if not(search_position == ''):
1045
+                    error_found = True
1046
+                    end_pos = '{}+{}c'.format(search_position, 5)
1047
+                    self.tag_add("error_highlight_inactive", search_position, end_pos)
1048
+                    search_position = '{}+{}c'.format(search_position, 1)  # point to the next character for new search
1049
+                else:
1050
+                    break
1051
+
1052
+        if error_found:
1053
+            if search_position == '':
1054
+                search_position = self.search("error", '1.0', stopindex="end",  nocase=1)  # new search
1055
+            else:                           # remove active highlight
1056
+                end_pos = '{}+{}c'.format(search_position, 5)
1057
+                start_pos = '{}+{}c'.format(search_position, -1)
1058
+                self.tag_remove("error_highlight_active", start_pos, end_pos)
1059
+            search_position = self.search("error", search_position, stopindex="end",  nocase=1)  # finds first occurrence AGAIN on the first time through
1060
+            if search_position == "":  # wrap around
1061
+                search_position = self.search("error", '1.0', stopindex="end", nocase=1)
1062
+            end_pos = '{}+{}c'.format(search_position, 5)
1063
+            self.tag_add("error_highlight_active", search_position, end_pos)      # add active highlight
1064
+            self.see(search_position)
1065
+            search_position = '{}+{}c'.format(search_position, 1)  # point to the next character for new search
1066
+
1067
+    def scroll_errors(self, event):
1068
+        self._scroll_errors()
1069
+
1070
+
1071
+    def _rebuild(self):
1072
+        #global board_name
1073
+        #global Marlin_ver
1074
+        #global target_env
1075
+        #board_name, Marlin_ver = get_board_name()
1076
+        #target_env = get_env(board_name, Marlin_ver)
1077
+        self.start_thread()
1078
+
1079
+    def rebuild(self, event):
1080
+        print "event happened"
1081
+        self._rebuild()
1082
+
1083
+
1084
+    def _open_selected_file(self):
1085
+        current_line = self.index('insert')
1086
+        line_start = current_line[ : current_line.find('.')] + '.0'
1087
+        line_end = current_line[ : current_line.find('.')] + '.200'
1088
+        self.mark_set("path_start", line_start)
1089
+        self.mark_set("path_end", line_end)
1090
+        path = self.get("path_start", "path_end")
1091
+        from_loc = path.find('from ')
1092
+        colon_loc = path.find(': ')
1093
+        if 0 <= from_loc and ((colon_loc == -1) or (from_loc < colon_loc)) :
1094
+          path = path [ from_loc + 5 : ]
1095
+        if 0 <= colon_loc:
1096
+          path = path [ :  colon_loc ]
1097
+        if 0 <= path.find('\\') or  0 <= path.find('/'):  # make sure it really contains a path
1098
+          open_file(path)
1099
+
1100
+
788 1101
     def _file_save_as(self):
789 1102
         self.filename = tkFileDialog.asksaveasfilename(defaultextension = '.txt')
790 1103
         f = open(self.filename, 'w')
@@ -833,7 +1146,7 @@ class output_window(Text):
833 1146
             pass
834 1147
 
835 1148
     def cut(self, event):
836
-        _cut(self)
1149
+        self._cut()
837 1150
 
838 1151
     def _copy(self):
839 1152
 
@@ -845,7 +1158,7 @@ class output_window(Text):
845 1158
             pass
846 1159
 
847 1160
     def copy(self, event):
848
-        _copy(self)
1161
+        self._copy()
849 1162
 
850 1163
     def _paste(self):
851 1164
 
@@ -867,40 +1180,7 @@ class output_window(Text):
867 1180
         if isok:
868 1181
             self.delete('1.0', 'end')
869 1182
 
870
-    def _place_cursor(self): # theme: terminal
871
-        '''check the position of the cursor against the last known position
872
-        every 15ms and update the cursorblock tag as needed'''
873
-
874
-        current_index = self.index('insert')
875
-
876
-        if self.cursor != current_index:
877
-            self.cursor = current_index
878
-            self.tag_delete('cursorblock')
879
-
880
-            start = self.index('insert')
881
-            end = self.index('insert+1c')
882
-
883
-            if start[0] != end[0]:
884
-                self.insert(start, ' ')
885
-                end = self.index('insert')
886
-
887
-            self.tag_add('cursorblock', start, end)
888
-            self.mark_set('insert', self.cursor)
889
-
890
-        self.after(15, self._place_cursor)
891
-
892
-    def _blink_cursor(self): # theme: terminal
893
-        '''alternate the background color of the cursorblock tagged text
894
-        every 600 milliseconds'''
895
-
896
-        if self.switch == self.fg:
897
-            self.switch = self.bg
898
-        else:
899
-            self.switch = self.fg
900
-
901
-        self.tag_config('cursorblock', background=self.switch)
902 1183
 
903
-        self.after(600, self._blink_cursor)
904 1184
 # end - output_window
905 1185
 
906 1186
 
@@ -923,6 +1203,9 @@ def main():
923 1203
         target_env = get_env(board_name, Marlin_ver)
924 1204
 
925 1205
         auto_build = output_window()
1206
+        if 0 <= target_env.find('USB1286'):
1207
+            copy_boards_dir()          # copy custom boards over to PlatformIO if using custom board
1208
+                                       #    causes 3-5 second delay in main window appearing
926 1209
         auto_build.start_thread()  # executes the "run_PIO" function
927 1210
 
928 1211
         auto_build.root.mainloop()

+ 115
- 0
buildroot/share/atom/create_custom_upload_command_CDC.py View File

@@ -0,0 +1,115 @@
1
+#
2
+#  Builds custom upload command
3
+#    1) Run platformio as a subprocess to find a COM port
4
+#    2) Build the upload command
5
+#    3) Exit and let upload tool do the work
6
+#
7
+#  This script runs between completion of the library/dependencies installation and compilation.
8
+#
9
+#  Will continue on if a COM port isn't found so that the compilation can be done.
10
+#
11
+
12
+import sys
13
+
14
+import subprocess
15
+
16
+
17
+import platform
18
+current_OS = platform.system()
19
+
20
+from SCons.Script import DefaultEnvironment
21
+
22
+env = DefaultEnvironment()
23
+
24
+com_first = ''
25
+com_last = ''
26
+com_CDC = ''
27
+description_first = ''
28
+description_last = ''
29
+description_CDC = ''
30
+
31
+#
32
+# grab the first com port that pops up unless we find one we know for sure
33
+# is a CDC device
34
+#
35
+def get_com_port(com_search_text, descr_search_text, start):
36
+
37
+    global com_first
38
+    global com_last
39
+    global com_CDC
40
+    global description_first
41
+    global description_last
42
+    global description_CDC
43
+
44
+
45
+    print '\nLooking for Serial Port\n'
46
+
47
+  # stream output from subprocess and split it into lines
48
+    pio_subprocess = subprocess.Popen(['platformio', 'device', 'list'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
49
+
50
+    looking_for_description = False
51
+    for line in iter(pio_subprocess.stdout.readline, ''):
52
+        if 0 <= line.find(com_search_text):
53
+          looking_for_description = True
54
+          com_last = line.replace('\n', '')
55
+          if com_first == '':
56
+            com_first = com_last
57
+        if 0 <= line.find(descr_search_text) and looking_for_description:
58
+          looking_for_description = False
59
+          description_last = line[ start : ]
60
+          if description_first == '':
61
+            description_first = description_last
62
+          if 0 <= description_last.find('CDC'):
63
+            com_CDC = com_last
64
+            description_CDC = description_last
65
+
66
+    if  com_CDC == '' and not(com_first == ''):
67
+        com_CDC = com_first
68
+        description_CDC = description_first
69
+    elif com_CDC == '':
70
+          com_CDC = 'COM_PORT_NOT_FOUND'
71
+
72
+    if com_CDC == 'COM_PORT_NOT_FOUND':
73
+        print com_CDC, '\n'
74
+    else:
75
+        print 'FOUND: ' ,com_CDC
76
+        print 'DESCRIPTION: ',  description_CDC , '\n'
77
+
78
+if current_OS == 'Windows':
79
+
80
+    get_com_port('COM', 'Hardware ID:', 13)
81
+
82
+    avrdude_conf_path =  env.get("PIOHOME_DIR") + '\\packages\\toolchain-atmelavr\\etc\\avrdude.conf'
83
+
84
+    source_path = env.get("PROJECTBUILD_DIR") + '\\' + env.get("PIOENV") + '\\firmware.hex'
85
+
86
+    upload_string = 'avrdude -p usb1286 -c avr109 -P ' + com_CDC + ' -C ' + avrdude_conf_path + ' -U flash:w:' + source_path + ':i'
87
+
88
+
89
+if current_OS == 'Darwin':  # MAC
90
+
91
+    get_com_port('usbmodem', 'Description:', 13)
92
+
93
+    avrdude_conf_path =  env.get("PIOHOME_DIR") + '/packages/toolchain-atmelavr/etc/avrdude.conf'
94
+
95
+    source_path = env.get("PROJECTBUILD_DIR") + '/' + env.get("PIOENV") + '/firmware.hex'
96
+
97
+    upload_string = 'avrdude -p usb1286 -c avr109 -P ' + com_CDC + ' -U flash:w:' + source_path + ':i'
98
+
99
+
100
+if current_OS == 'Linux':
101
+
102
+    get_com_port('/dev/tty', 'Description:', 13)
103
+
104
+    avrdude_conf_path =  env.get("PIOHOME_DIR") + '/packages/toolchain-atmelavr/etc/avrdude.conf'
105
+
106
+    source_path = env.get("PROJECTBUILD_DIR") + '/' + env.get("PIOENV") + '/firmware.hex'
107
+
108
+    upload_string = 'avrdude -p usb1286 -c avr109 -P ' + com_CDC + ' -U flash:w:' + source_path + ':i'
109
+
110
+
111
+env.Replace(
112
+     UPLOADCMD = upload_string,
113
+     MAXIMUM_RAM_SIZE = 8192,
114
+     MAXIMUM_SIZE = 130048
115
+)

+ 37
- 0
buildroot/share/atom/create_custom_upload_command_DFU.py View File

@@ -0,0 +1,37 @@
1
+#
2
+#  Builds custom upload command
3
+#    1) Run platformio as a subprocess to find a COM port
4
+#    2) Build the upload command
5
+#    3) Exit and let upload tool do the work
6
+#
7
+#  This script runs between completion of the library/dependencies installation and compilation.
8
+#
9
+#  Will continue on if a COM port isn't found so that the compilation can be done.
10
+#
11
+
12
+import sys
13
+from SCons.Script import DefaultEnvironment
14
+
15
+import platform
16
+current_OS = platform.system()
17
+
18
+env = DefaultEnvironment()
19
+
20
+if current_OS == 'Windows':
21
+    avrdude_conf_path =  env.get("PIOHOME_DIR") + '\\packages\\toolchain-atmelavr\\etc\\avrdude.conf'
22
+
23
+    source_path = env.get("PROJECTBUILD_DIR") + '\\' + env.get("PIOENV") + '\\firmware.hex'
24
+
25
+    upload_string = 'avrdude -p usb1286 -c flip1 -C ' + avrdude_conf_path + ' -U flash:w:' + source_path + ':i'
26
+
27
+else:
28
+    source_path = env.get("PROJECTBUILD_DIR") + '/' + env.get("PIOENV") + '/firmware.hex'
29
+
30
+    upload_string = 'avrdude -p usb1286 -c flip1 -U flash:w:' + source_path + ':i'
31
+
32
+
33
+env.Replace(
34
+     UPLOADCMD = upload_string,
35
+     MAXIMUM_RAM_SIZE = 8192,
36
+     MAXIMUM_SIZE = 130048
37
+)

+ 39
- 4
platformio.ini View File

@@ -74,6 +74,39 @@ src_filter    = ${common.default_src_filter}
74 74
 monitor_speed = 250000
75 75
 
76 76
 #
77
+# AT90USB1286 boards using CDC bootloader
78
+# - BRAINWAVE
79
+# - BRAINWAVE_PRO
80
+# - SAV_MKI
81
+# - TEENSYLU
82
+#
83
+[env:at90USB1286_CDC]
84
+platform      = teensy
85
+framework     = arduino
86
+board         = at90USB1286
87
+build_flags   = ${common.build_flags}
88
+lib_deps      = ${common.lib_deps}
89
+lib_ldf_mode  = deep+
90
+src_filter    = ${common.default_src_filter}
91
+extra_scripts = pre:buildroot/share/atom/create_custom_upload_command_CDC.py
92
+
93
+#
94
+# AT90USB1286 boards using DFU bootloader
95
+# - PrintrBoard
96
+# - PrintrBoard Rev.F
97
+# - ? 5DPRINT ?
98
+#
99
+[env:at90USB1286_DFU]
100
+platform      = teensy
101
+framework     = arduino
102
+board         = at90USB1286
103
+build_flags   = ${common.build_flags}
104
+lib_deps      = ${common.lib_deps}
105
+lib_ldf_mode  = deep+
106
+src_filter    = ${common.default_src_filter}
107
+extra_scripts = pre:buildroot/share/atom/create_custom_upload_command_DFU.py
108
+
109
+#
77 110
 # Due (Atmel SAM3X8E ARM Cortex-M3)
78 111
 #
79 112
 #  - RAMPS4DUE
@@ -223,6 +256,9 @@ lib_deps      = ${common.lib_deps}
223 256
 src_filter    = ${common.default_src_filter}
224 257
 monitor_speed = 250000
225 258
 
259
+#
260
+# STM32F103RE
261
+#
226 262
 [env:STM32F1]
227 263
 platform      = ststm32
228 264
 framework     = arduino
@@ -242,6 +278,9 @@ lib_ldf_mode  = 1
242 278
 src_filter    = ${common.default_src_filter}
243 279
 monitor_speed = 250000
244 280
 
281
+#
282
+# STM32F4
283
+#
245 284
 [env:STM32F4]
246 285
 platform      = ststm32
247 286
 framework     = arduino
@@ -255,10 +294,6 @@ monitor_speed = 250000
255 294
 #
256 295
 # Teensy++ 2.0
257 296
 #
258
-# - PrintrBoard
259
-# - PrintrBoard Rev.F
260
-# - Brainwave Pro
261
-#
262 297
 [env:teensy20]
263 298
 platform      = teensy
264 299
 framework     = arduino

Loading…
Cancel
Save