├── doc
└── main_window.png
├── .gitignore
├── README.md
├── flasher.py
└── flasher_gui.py
/doc/main_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/molejar/jlink-flasher/HEAD/doc/main_window.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | build
3 |
4 | flasher.spec
5 | flasher.cfg
6 | script.jlink
7 | mcu.db
8 |
9 | *.pyc
10 |
11 | # Intelij files
12 | .idea
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | JLink Flasher
2 | =============
3 |
4 | [SEGGER J-Links](http://segger.com/jlink-debug-probes.html) are the most widely used line of debug probes available today. Any of this J-Link
5 | debug probe can be also used as flash programmer, what can save you a lot of time and money in
6 | developing a new product. For this purpose exist Windows application [J-Flash](http://segger.com/jflash.html) developed by SEGGER,
7 | which can program internal and external flash on ARM/Cortex devices. Because I didn't found any
8 | similar tool for Linux, thus I have decided to create something useful by myself. And here is my first
9 | version of J-Link programmer GUI based on wxPython.
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/flasher.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from __future__ import print_function
4 |
5 | import os, sys, wx
6 | import ConfigParser
7 | import subprocess
8 | import threading
9 | import platform
10 | import flasher_gui
11 |
12 | #wx.Log_EnableLogging()
13 |
14 |
15 |
16 | class JLink(object):
17 | def __init__(self):
18 | """
19 | JLink control class
20 |
21 | """
22 | if platform.system() is "Windows":
23 | self.os_type = "win"
24 | else:
25 | self.os_type = "linux"
26 | #
27 | self.pwd = os.path.dirname(os.path.realpath(sys.argv[0]))
28 | self.mcu_db_file = os.path.join(self.pwd, "mcu.db")
29 | self.script_file = os.path.join(self.pwd, "script.jlink")
30 | self.config_file = os.path.join(self.pwd, "flasher.cfg")
31 | self.supported_speeds = ["100", "200", "400", "800", "1000"]
32 | self.supported_interfaces = ["JTAG", "SWD"]
33 | # Configurable var.
34 | self.app_file = ""
35 | self.supported_chips = []
36 | self.LoadConfig()
37 |
38 |
39 | def __del__(self):
40 | pass
41 |
42 | def LoadConfig(self):
43 | config = ConfigParser.ConfigParser()
44 | if config.read(self.config_file):
45 | self.app_file = config.get('Settings', 'app_file')
46 | self.supported_chips = config.get('Settings', 'usr_chips').split(', ')
47 | return True
48 | else:
49 | self.app_file = "Set The JLink.exe path"
50 | self.supported_chips = ["MKL25Z128xxx4", "MKL46Z256xxx4"]
51 | return False
52 |
53 |
54 | def SaveConfig(self):
55 | config = ConfigParser.ConfigParser()
56 | config.add_section("Settings")
57 | config.set('Settings', 'app_file', self.app_file)
58 | config.set('Settings', 'usr_chips', ', '.join(self.supported_chips))
59 | # Writing our configuration file to 'example.cfg'
60 | with open(self.config_file, 'wb') as configfile:
61 | config.write(configfile)
62 | configfile.close()
63 |
64 |
65 | def BuildScript(self, cmd_type, chip_type, interface=1, speed='100', image=None, offset='0x00000000'):
66 | with open(self.script_file, 'w') as jsc_file:
67 | jsc_file.write('si ' + str(interface) + '\n')
68 | jsc_file.write('speed ' + self.supported_speeds[speed] + '\n')
69 | jsc_file.write('device ' + chip_type + '\n')
70 |
71 | if cmd_type == 'Erase':
72 | jsc_file.write('erase\n')
73 | elif cmd_type == 'Unlock':
74 | jsc_file.write('unlock kinetis\n')
75 | elif cmd_type == 'Program':
76 | #jsc_file.write('erase\n')
77 | jsc_file.write('loadbin ' + image + ', ' + offset + '\n')
78 | else:
79 | print("BuildScript: Unsuported CMD")
80 |
81 | jsc_file.write('r\n')
82 | jsc_file.write('exit\n')
83 | jsc_file.close()
84 | return True
85 |
86 |
87 | def UpdateChipsColection(self):
88 | with open(self.script_file, 'w') as jsc_file:
89 | jsc_file.write('ExpDevList ' + self.mcu_db_file + '\n')
90 | jsc_file.write('exit\n')
91 | jsc_file.close()
92 | # Clear file if exist
93 | fd = open(self.mcu_db_file, 'w')
94 | fd.close()
95 |
96 | # Execute JLinkExe and generate supported MCU collection
97 | subprocess.call("\"" + self.app_file + "\"" + " -CommanderScript " + self.script_file, shell=True)
98 | return True
99 |
100 |
101 | def LoadChipsColection(self):
102 | mcu_db = []
103 | if os.path.isfile(self.mcu_db_file) and os.access(self.mcu_db_file, os.R_OK):
104 | with open(self.mcu_db_file, 'r') as fd_r:
105 | lines = fd_r.readlines()
106 | fd_r.close()
107 | for line in lines[1:]:
108 | line = line.strip('\r\n')
109 | line = line.replace('"', '')
110 | data = line.split(', ', 3)
111 | mcu_db.append((data[0], data[1], data[2]))
112 | return mcu_db
113 |
114 |
115 |
116 | class SettingsGUI(flasher_gui.ConfigDialog):
117 | def __init__(self, parent, jlink):
118 | flasher_gui.ConfigDialog.__init__(self, parent)
119 | self.jlink = jlink
120 | if self.jlink.app_file != "":
121 | self.m_textCtrl_jlink_path.SetValue(self.jlink.app_file)
122 | self.m_button_db_update.Enable(True)
123 | self.m_gauge_status.Enable(True)
124 | self.m_textCtrl_db_info.Enable(True)
125 | if os.path.isfile(self.jlink.mcu_db_file):
126 | self.m_textCtrl_db_info.Value = "OK"
127 | self.m_textCtrl_db_info.SetBackgroundColour(wx.Colour(200, 250, 160))
128 |
129 | def __del__(self):
130 | pass
131 |
132 | def OnSelectDir(self, event):
133 | if self.jlink.os_type is "win":
134 | file_filter = "JLink.exe |JLink.exe"
135 | else:
136 | file_filter = "JLinkExe |JLinkExe"
137 | path = wx.FileDialog(self, "Found JLink Install Dir",
138 | os.path.dirname(self.m_textCtrl_jlink_path.Value),
139 | "", file_filter, wx.FD_FILE_MUST_EXIST)
140 | if path.ShowModal() == wx.ID_OK:
141 | self.jlink.app_file = path.Path
142 | self.m_textCtrl_jlink_path.SetValue(path.Path)
143 | self.m_button_db_update.Enable(True)
144 | self.m_gauge_status.Enable(True)
145 | self.m_textCtrl_db_info.Enable(True)
146 |
147 | event.Skip()
148 |
149 | def OnUpdateDB(self, event):
150 | self.m_gauge_status.SetValue(40)
151 | self.m_gauge_status.Update()
152 | if self.jlink.UpdateChipsColection() is True:
153 | self.m_gauge_status.SetValue(100)
154 | self.m_gauge_status.Update()
155 | self.m_textCtrl_db_info.Value = "OK"
156 | self.m_textCtrl_db_info.SetBackgroundColour(wx.Colour(200, 250, 160))
157 | else:
158 | self.m_textCtrl_db_info.Value = "ERROR"
159 | self.m_textCtrl_db_info.SetBackgroundColour(wx.Colour(250, 200, 100))
160 | event.Skip()
161 |
162 |
163 | class AddGUI(flasher_gui.TargetDialog):
164 | def __init__(self, parent, jlink):
165 | flasher_gui.TargetDialog.__init__(self, parent)
166 | self.jlink = jlink
167 |
168 | self.m_choice_vendor.AppendItems(["All",
169 | "Actel",
170 | "Analog",
171 | "Atmel",
172 | "Cypress",
173 | "Energy Micro",
174 | "Freescale",
175 | "Fujitsu",
176 | "Luminary",
177 | "Microchip",
178 | "Nordic Semi",
179 | "Nuvoton",
180 | "NXP",
181 | "Renesas",
182 | "Samsung",
183 | "Silicon Labs",
184 | "ST",
185 | "TI",
186 | "Toshiba"])
187 | self.m_choice_vendor.SetSelection(0)
188 | self.m_choice_core.AppendItems(["All",
189 | "Cortex-M0",
190 | "Cortex-M3",
191 | "Cortex-M4",
192 | "Cortex-R4",
193 | "ARM966E-S",
194 | "Cortex-A9"])
195 | self.m_choice_core.SetSelection(0)
196 | self.LoadSupportedChips("All", "All")
197 | self.LoadUsrChips()
198 |
199 | def __del__(self):
200 | pass
201 |
202 | def OnVendorChoice(self, event):
203 | self.LoadSupportedChips(self.m_choice_vendor.GetStringSelection(), self.m_choice_core.GetStringSelection())
204 | event.Skip()
205 |
206 |
207 | def OnCoreChoice(self, event):
208 | self.LoadSupportedChips(self.m_choice_vendor.GetStringSelection(), self.m_choice_core.GetStringSelection())
209 | event.Skip()
210 |
211 | def OnAdd( self, event ):
212 | index = self.m_listCtrl_mcu_db.GetFirstSelected()
213 | item = self.m_listCtrl_mcu_db.GetItem(index, 1).GetText()
214 | self.m_listCtrl_usr_db.InsertStringItem(self.m_listCtrl_usr_db.GetItemCount(), item)
215 | event.Skip()
216 |
217 | def OnDelete( self, event ):
218 | index = self.m_listCtrl_usr_db.GetFirstSelected()
219 | self.m_listCtrl_usr_db.DeleteItem(index)
220 | event.Skip()
221 |
222 |
223 | def LoadSupportedChips(self, vendor, core):
224 | self.m_listCtrl_mcu_db.ClearAll()
225 | self.m_listCtrl_mcu_db.InsertColumn(0, "Vendor", width=160)
226 | self.m_listCtrl_mcu_db.InsertColumn(1, "Device", width=250)
227 | self.m_listCtrl_mcu_db.InsertColumn(2, "Core", width=150)
228 | mcu_db = self.jlink.LoadChipsColection()
229 | if mcu_db != []:
230 | for item in mcu_db:
231 | if (vendor == "All" or item[0] == vendor) and (core == "All" or item[2] == core):
232 | self.m_listCtrl_mcu_db.Append(item)
233 |
234 | def LoadUsrChips(self):
235 | self.m_listCtrl_usr_db.ClearAll()
236 | self.m_listCtrl_usr_db.InsertColumn(0, "Device", width=560)
237 | for item in self.jlink.supported_chips:
238 | self.m_listCtrl_usr_db.Append([item])
239 |
240 |
241 | class FlasherGUI(flasher_gui.AppFrame):
242 | def __init__(self, parent):
243 | flasher_gui.AppFrame.__init__(self, parent)
244 |
245 | self.jlink = JLink()
246 |
247 | self.m_choice_target.AppendItems(self.jlink.supported_chips)
248 | self.m_choice_target.SetSelection(0)
249 | self.m_choice_dbg_interface.AppendItems(self.jlink.supported_interfaces)
250 | self.m_choice_dbg_interface.SetSelection(1)
251 | for n in self.jlink.supported_speeds:
252 | self.m_choice_speed.Append(n + ' kHz')
253 | self.m_choice_speed.SetSelection(4)
254 | #self.m_textCtrl_log.AppendText(self.jlink.pwd)
255 |
256 | def __del__(self):
257 | pass
258 |
259 | def OnOpen(self, event):
260 | event.Skip()
261 |
262 | def OnSave(self, event):
263 | event.Skip()
264 |
265 | def OnExit(self, event):
266 | exit()
267 |
268 | def OnSettings(self, event):
269 | m_setting_dialog = SettingsGUI(parent=None, jlink=self.jlink)
270 | if m_setting_dialog.ShowModal() == wx.ID_CANCEL:
271 | self.m_textCtrl_log.AppendText("OK\n")
272 | self.jlink.app_file = m_setting_dialog.m_textCtrl_jlink_path.Value
273 | self.jlink.SaveConfig()
274 | m_setting_dialog.Destroy()
275 | event.Skip()
276 |
277 | def OnAbout(self, event):
278 | info = wx.AboutDialogInfo()
279 | info.Name = "JLink Flasher"
280 | info.Version = "0.0.1 Beta"
281 | info.Copyright = "(C) 2014 Martin Olejar"
282 | info.WebSite = ("http://www.segger.com", "SEGGER Home Page")
283 | wx.AboutBox(info)
284 | event.Skip()
285 |
286 | def OnTargetAdd(self, event):
287 | m_add_dialog = AddGUI(parent=None, jlink=self.jlink)
288 | if m_add_dialog.ShowModal() == wx.ID_OK:
289 | self.m_choice_target.Clear()
290 | i = 0
291 | self.jlink.supported_chips = []
292 | while i < m_add_dialog.m_listCtrl_usr_db.GetItemCount():
293 | item = m_add_dialog.m_listCtrl_usr_db.GetItem(i, 0).GetText()
294 | self.m_choice_target.Append(item)
295 | self.jlink.supported_chips.append(item)
296 | i += 1
297 | self.m_choice_target.SetSelection(0)
298 | self.jlink.SaveConfig()
299 | m_add_dialog.Destroy()
300 | event.Skip()
301 |
302 | def OnImageUpdated(self, event):
303 | if os.path.exists(self.m_filePicker_targetImage.Path):
304 | self.m_button_flash.Enable(True)
305 | self.m_textCtrl_offset.Enable(True)
306 | else:
307 | self.m_button_flash.Enable(False)
308 | self.m_textCtrl_offset.Enable(False)
309 | event.Skip()
310 |
311 | def OnLogEnable(self, event):
312 | if self.m_textCtrl_log.IsShown:
313 | self.m_textCtrl_log.Hide()
314 | else:
315 | self.m_textCtrl_log.Shown()
316 | event.Skip()
317 |
318 | def OnResetTarget(self, event):
319 | self.Execute('Reset')
320 | event.Skip()
321 |
322 | def OnUnlockTarget(self, event):
323 | self.Execute('Unlock')
324 | event.Skip()
325 |
326 | def OnEraseTarget(self, event):
327 | self.Execute('Erase')
328 | event.Skip()
329 |
330 | def OnFlashTarget(self, event):
331 | self.Execute('Program')
332 | event.Skip()
333 |
334 | def Execute(self, cmd):
335 | self.m_textCtrl_log.Clear()
336 | self.m_textCtrl_log.AppendText("\n<<<< " + cmd + " Target >>>> \n\n")
337 | status = self.jlink.BuildScript(cmd_type=cmd,
338 | chip_type=self.m_choice_target.GetStringSelection(),
339 | interface=self.m_choice_dbg_interface.GetSelection(),
340 | speed=self.m_choice_speed.GetSelection(),
341 | image=self.m_filePicker_targetImage.Path,
342 | offset=self.m_textCtrl_offset.Value)
343 | if status is True:
344 | try:
345 | thread = threading.Thread(target=self.run)
346 | thread.setDaemon(True)
347 | thread.start()
348 | except:
349 | self.m_textCtrl_log.AppendText("\n<<<< " + cmd + " Error >>>> \n")
350 |
351 |
352 | def run(self):
353 | for line in subprocess.Popen("\"" + self.jlink.app_file + "\"" + " -CommanderScript " + self.jlink.script_file,
354 | shell=True,
355 | stdout=subprocess.PIPE,
356 | stderr=subprocess.STDOUT).stdout:
357 | wx.CallAfter(self.m_textCtrl_log.AppendText, line)
358 |
359 |
360 | class MyApp(wx.App):
361 | def OnInit(self):
362 | frame = FlasherGUI(None)
363 | frame.Show(True)
364 | return True
365 |
366 |
367 | if __name__ == '__main__':
368 | app = MyApp(0)
369 | app.MainLoop()
370 |
--------------------------------------------------------------------------------
/flasher_gui.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | ###########################################################################
4 | ## Python code generated with wxFormBuilder (version Jun 5 2014)
5 | ## http://www.wxformbuilder.org/
6 | ##
7 | ## PLEASE DO "NOT" EDIT THIS FILE!
8 | ###########################################################################
9 |
10 | import wx
11 | import wx.xrc
12 |
13 | ###########################################################################
14 | ## Class AppFrame
15 | ###########################################################################
16 |
17 | class AppFrame ( wx.Frame ):
18 |
19 | def __init__( self, parent ):
20 | wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"JLink Flasher", pos = wx.DefaultPosition, size = wx.Size( 550,500 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
21 |
22 | self.SetSizeHintsSz( wx.Size( 550,500 ), wx.DefaultSize )
23 | self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_MENU ) )
24 |
25 | self.m_menubar = wx.MenuBar( 0 )
26 | self.m_menu_file = wx.Menu()
27 | self.m_menuItem_exit = wx.MenuItem( self.m_menu_file, wx.ID_ANY, u"&Exit"+ u"\t" + u"CTRL+X", wx.EmptyString, wx.ITEM_NORMAL )
28 | self.m_menuItem_exit.SetBitmap( wx.ArtProvider.GetBitmap( wx.ART_QUIT, ) )
29 | self.m_menu_file.AppendItem( self.m_menuItem_exit )
30 |
31 | self.m_menubar.Append( self.m_menu_file, u"&File" )
32 |
33 | self.m_menu_tools = wx.Menu()
34 | self.m_menuItem_settings = wx.MenuItem( self.m_menu_tools, wx.ID_ANY, u"&Settings"+ u"\t" + u"CTRL+S", wx.EmptyString, wx.ITEM_NORMAL )
35 | self.m_menuItem_settings.SetBitmap( wx.NullBitmap )
36 | self.m_menu_tools.AppendItem( self.m_menuItem_settings )
37 |
38 | self.m_menubar.Append( self.m_menu_tools, u"&Tools" )
39 |
40 | self.m_menu_help = wx.Menu()
41 | self.m_menuItem_about = wx.MenuItem( self.m_menu_help, wx.ID_ANY, u"&About.."+ u"\t" + u"F1", wx.EmptyString, wx.ITEM_NORMAL )
42 | self.m_menuItem_about.SetBitmap( wx.ArtProvider.GetBitmap( wx.ART_HELP_FOLDER, ) )
43 | self.m_menu_help.AppendItem( self.m_menuItem_about )
44 |
45 | self.m_menubar.Append( self.m_menu_help, u"&Help" )
46 |
47 | self.SetMenuBar( self.m_menubar )
48 |
49 | fgSizer = wx.FlexGridSizer( 2, 1, 0, 0 )
50 | fgSizer.AddGrowableCol( 0 )
51 | fgSizer.AddGrowableRow( 0 )
52 | fgSizer.SetFlexibleDirection( wx.BOTH )
53 | fgSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
54 |
55 | self.m_panel2 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
56 | self.m_panel2.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_MENU ) )
57 |
58 | fgSizer31 = wx.FlexGridSizer( 4, 1, 0, 0 )
59 | fgSizer31.AddGrowableCol( 0 )
60 | fgSizer31.AddGrowableRow( 2 )
61 | fgSizer31.SetFlexibleDirection( wx.BOTH )
62 | fgSizer31.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
63 |
64 | fgSizer3 = wx.FlexGridSizer( 3, 2, 0, 0 )
65 | fgSizer3.AddGrowableCol( 1 )
66 | fgSizer3.SetFlexibleDirection( wx.BOTH )
67 | fgSizer3.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
68 |
69 | self.m_staticText1 = wx.StaticText( self.m_panel2, wx.ID_ANY, u"Target:", wx.DefaultPosition, wx.DefaultSize, 0 )
70 | self.m_staticText1.Wrap( -1 )
71 | fgSizer3.Add( self.m_staticText1, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
72 |
73 | bSizer6 = wx.BoxSizer( wx.HORIZONTAL )
74 |
75 | m_choice_targetChoices = []
76 | self.m_choice_target = wx.Choice( self.m_panel2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice_targetChoices, wx.CB_SORT )
77 | self.m_choice_target.SetSelection( 0 )
78 | self.m_choice_target.SetFont( wx.Font( 9, 74, 90, 90, False, "Sans" ) )
79 | self.m_choice_target.SetToolTipString( u"Select Target MCU" )
80 |
81 | bSizer6.Add( self.m_choice_target, 1, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.BOTTOM|wx.LEFT, 5 )
82 |
83 | self.m_button_add = wx.Button( self.m_panel2, wx.ID_ANY, u"Add", wx.DefaultPosition, wx.DefaultSize, 0 )
84 | self.m_button_add.SetFont( wx.Font( 9, 74, 90, 92, False, "Sans" ) )
85 |
86 | bSizer6.Add( self.m_button_add, 0, wx.ALL, 5 )
87 |
88 |
89 | fgSizer3.Add( bSizer6, 1, wx.EXPAND, 5 )
90 |
91 | self.m_staticText2 = wx.StaticText( self.m_panel2, wx.ID_ANY, u"Image:", wx.DefaultPosition, wx.DefaultSize, 0 )
92 | self.m_staticText2.Wrap( -1 )
93 | fgSizer3.Add( self.m_staticText2, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
94 |
95 | self.m_filePicker_targetImage = wx.FilePickerCtrl( self.m_panel2, wx.ID_ANY, wx.EmptyString, u"Select a file", u"BIN files (*.bin)|*.bin|HEX files (*.hex)|*.hex", wx.DefaultPosition, wx.DefaultSize, wx.FLP_DEFAULT_STYLE )
96 | self.m_filePicker_targetImage.SetFont( wx.Font( 9, 74, 90, 90, False, "Sans" ) )
97 |
98 | fgSizer3.Add( self.m_filePicker_targetImage, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 5 )
99 |
100 | self.m_staticText_offset = wx.StaticText( self.m_panel2, wx.ID_ANY, u"Offset:", wx.DefaultPosition, wx.DefaultSize, 0 )
101 | self.m_staticText_offset.Wrap( -1 )
102 | fgSizer3.Add( self.m_staticText_offset, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
103 |
104 | bSizer9 = wx.BoxSizer( wx.HORIZONTAL )
105 |
106 | self.m_textCtrl_offset = wx.TextCtrl( self.m_panel2, wx.ID_ANY, u"0x00000000", wx.DefaultPosition, wx.DefaultSize, 0 )
107 | self.m_textCtrl_offset.SetFont( wx.Font( 9, 74, 90, 90, False, "Sans" ) )
108 | self.m_textCtrl_offset.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) )
109 | self.m_textCtrl_offset.Enable( False )
110 | self.m_textCtrl_offset.SetToolTipString( u"Set Image Offset" )
111 | self.m_textCtrl_offset.SetMinSize( wx.Size( 100,-1 ) )
112 |
113 | bSizer9.Add( self.m_textCtrl_offset, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5 )
114 |
115 |
116 | bSizer9.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
117 |
118 | self.m_staticText8 = wx.StaticText( self.m_panel2, wx.ID_ANY, u"Bus Type:", wx.DefaultPosition, wx.DefaultSize, 0 )
119 | self.m_staticText8.Wrap( -1 )
120 | bSizer9.Add( self.m_staticText8, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
121 |
122 | m_choice_dbg_interfaceChoices = []
123 | self.m_choice_dbg_interface = wx.Choice( self.m_panel2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice_dbg_interfaceChoices, 0 )
124 | self.m_choice_dbg_interface.SetSelection( 0 )
125 | self.m_choice_dbg_interface.SetMinSize( wx.Size( 110,-1 ) )
126 |
127 | bSizer9.Add( self.m_choice_dbg_interface, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5 )
128 |
129 |
130 | bSizer9.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
131 |
132 | self.m_staticText7 = wx.StaticText( self.m_panel2, wx.ID_ANY, u"Speed:", wx.DefaultPosition, wx.DefaultSize, 0 )
133 | self.m_staticText7.Wrap( -1 )
134 | bSizer9.Add( self.m_staticText7, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
135 |
136 | m_choice_speedChoices = []
137 | self.m_choice_speed = wx.Choice( self.m_panel2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice_speedChoices, 0 )
138 | self.m_choice_speed.SetSelection( 0 )
139 | self.m_choice_speed.SetMinSize( wx.Size( 120,-1 ) )
140 |
141 | bSizer9.Add( self.m_choice_speed, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5 )
142 |
143 |
144 | fgSizer3.Add( bSizer9, 1, wx.EXPAND, 5 )
145 |
146 |
147 | fgSizer31.Add( fgSizer3, 1, wx.EXPAND|wx.ALL, 5 )
148 |
149 | bSizer3 = wx.BoxSizer( wx.HORIZONTAL )
150 |
151 | self.m_staticline3 = wx.StaticLine( self.m_panel2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
152 | bSizer3.Add( self.m_staticline3, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
153 |
154 | self.m_staticText5 = wx.StaticText( self.m_panel2, wx.ID_ANY, u"<< Log >>", wx.DefaultPosition, wx.DefaultSize, 0 )
155 | self.m_staticText5.Wrap( -1 )
156 | self.m_staticText5.SetForegroundColour( wx.Colour( 80, 80, 80 ) )
157 |
158 | bSizer3.Add( self.m_staticText5, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
159 |
160 | self.m_staticline1 = wx.StaticLine( self.m_panel2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
161 | self.m_staticline1.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) )
162 |
163 | bSizer3.Add( self.m_staticline1, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
164 |
165 |
166 | fgSizer31.Add( bSizer3, 1, wx.EXPAND|wx.RIGHT|wx.LEFT, 5 )
167 |
168 | bSizer4 = wx.BoxSizer( wx.VERTICAL )
169 |
170 | self.m_textCtrl_log = wx.TextCtrl( self.m_panel2, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.HSCROLL|wx.TE_CHARWRAP|wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_WORDWRAP )
171 | self.m_textCtrl_log.SetForegroundColour( wx.Colour( 15, 228, 100 ) )
172 | self.m_textCtrl_log.SetBackgroundColour( wx.Colour( 0, 0, 0 ) )
173 |
174 | bSizer4.Add( self.m_textCtrl_log, 1, wx.EXPAND, 12 )
175 |
176 |
177 | fgSizer31.Add( bSizer4, 1, wx.EXPAND|wx.RIGHT|wx.LEFT, 12 )
178 |
179 | bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
180 |
181 | self.m_button_unlock = wx.Button( self.m_panel2, wx.ID_ANY, u"Unlock", wx.DefaultPosition, wx.DefaultSize, 0 )
182 | self.m_button_unlock.SetFont( wx.Font( 9, 74, 90, 92, False, "Sans" ) )
183 |
184 | bSizer2.Add( self.m_button_unlock, 0, wx.ALL, 5 )
185 |
186 |
187 | bSizer2.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
188 |
189 | self.m_button_reset = wx.Button( self.m_panel2, wx.ID_ANY, u"Reset", wx.DefaultPosition, wx.DefaultSize, 0 )
190 | self.m_button_reset.SetFont( wx.Font( 9, 74, 90, 92, False, "Sans" ) )
191 |
192 | bSizer2.Add( self.m_button_reset, 0, wx.ALL, 5 )
193 |
194 |
195 | bSizer2.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
196 |
197 | self.m_button_erase = wx.Button( self.m_panel2, wx.ID_ANY, u"Erase", wx.DefaultPosition, wx.DefaultSize, 0 )
198 | self.m_button_erase.SetFont( wx.Font( 9, 74, 90, 92, False, "Sans" ) )
199 |
200 | bSizer2.Add( self.m_button_erase, 0, wx.ALL, 5 )
201 |
202 |
203 | bSizer2.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
204 |
205 | self.m_button_flash = wx.Button( self.m_panel2, wx.ID_ANY, u"Flash", wx.DefaultPosition, wx.DefaultSize, 0 )
206 | self.m_button_flash.SetFont( wx.Font( 9, 74, 90, 92, False, "Sans" ) )
207 | self.m_button_flash.Enable( False )
208 |
209 | bSizer2.Add( self.m_button_flash, 0, wx.ALL, 5 )
210 |
211 |
212 | fgSizer31.Add( bSizer2, 1, wx.EXPAND|wx.TOP|wx.RIGHT|wx.LEFT, 6 )
213 |
214 |
215 | self.m_panel2.SetSizer( fgSizer31 )
216 | self.m_panel2.Layout()
217 | fgSizer31.Fit( self.m_panel2 )
218 | fgSizer.Add( self.m_panel2, 0, wx.EXPAND |wx.ALL, 5 )
219 |
220 |
221 | self.SetSizer( fgSizer )
222 | self.Layout()
223 | self.m_statusBar = self.CreateStatusBar( 1, wx.ST_SIZEGRIP, wx.ID_ANY )
224 |
225 | self.Centre( wx.BOTH )
226 |
227 | # Connect Events
228 | self.Bind( wx.EVT_MENU, self.OnExit, id = self.m_menuItem_exit.GetId() )
229 | self.Bind( wx.EVT_MENU, self.OnSettings, id = self.m_menuItem_settings.GetId() )
230 | self.Bind( wx.EVT_MENU, self.OnAbout, id = self.m_menuItem_about.GetId() )
231 | self.m_button_add.Bind( wx.EVT_BUTTON, self.OnTargetAdd )
232 | self.m_filePicker_targetImage.Bind( wx.EVT_FILEPICKER_CHANGED, self.OnImageUpdated )
233 | self.m_button_unlock.Bind( wx.EVT_BUTTON, self.OnUnlockTarget )
234 | self.m_button_reset.Bind( wx.EVT_BUTTON, self.OnResetTarget )
235 | self.m_button_erase.Bind( wx.EVT_BUTTON, self.OnEraseTarget )
236 | self.m_button_flash.Bind( wx.EVT_BUTTON, self.OnFlashTarget )
237 |
238 | def __del__( self ):
239 | pass
240 |
241 |
242 | # Virtual event handlers, overide them in your derived class
243 | def OnExit( self, event ):
244 | event.Skip()
245 |
246 | def OnSettings( self, event ):
247 | event.Skip()
248 |
249 | def OnAbout( self, event ):
250 | event.Skip()
251 |
252 | def OnTargetAdd( self, event ):
253 | event.Skip()
254 |
255 | def OnImageUpdated( self, event ):
256 | event.Skip()
257 |
258 | def OnUnlockTarget( self, event ):
259 | event.Skip()
260 |
261 | def OnResetTarget( self, event ):
262 | event.Skip()
263 |
264 | def OnEraseTarget( self, event ):
265 | event.Skip()
266 |
267 | def OnFlashTarget( self, event ):
268 | event.Skip()
269 |
270 |
271 | ###########################################################################
272 | ## Class ConfigDialog
273 | ###########################################################################
274 |
275 | class ConfigDialog ( wx.Dialog ):
276 |
277 | def __init__( self, parent ):
278 | wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Flasher Settings", pos = wx.DefaultPosition, size = wx.Size( 480,160 ), style = wx.DEFAULT_DIALOG_STYLE|wx.STAY_ON_TOP )
279 |
280 | self.SetSizeHintsSz( wx.Size( -1,-1 ), wx.DefaultSize )
281 |
282 | bSizer9 = wx.BoxSizer( wx.VERTICAL )
283 |
284 | fgSizer5 = wx.FlexGridSizer( 3, 2, 0, 0 )
285 | fgSizer5.AddGrowableCol( 1 )
286 | fgSizer5.SetFlexibleDirection( wx.BOTH )
287 | fgSizer5.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
288 |
289 | self.m_staticText4 = wx.StaticText( self, wx.ID_ANY, u"JLink Path:", wx.DefaultPosition, wx.DefaultSize, 0 )
290 | self.m_staticText4.Wrap( -1 )
291 | fgSizer5.Add( self.m_staticText4, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
292 |
293 | bSizer10 = wx.BoxSizer( wx.HORIZONTAL )
294 |
295 | self.m_textCtrl_jlink_path = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_READONLY )
296 | self.m_textCtrl_jlink_path.SetMinSize( wx.Size( -1,26 ) )
297 |
298 | bSizer10.Add( self.m_textCtrl_jlink_path, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
299 |
300 | self.m_bt_jlink_path = wx.Button( self, wx.ID_ANY, u"...", wx.DefaultPosition, wx.DefaultSize, 0 )
301 | bSizer10.Add( self.m_bt_jlink_path, 0, wx.ALL, 5 )
302 |
303 |
304 | fgSizer5.Add( bSizer10, 1, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5 )
305 |
306 | self.m_staticText6 = wx.StaticText( self, wx.ID_ANY, u"MCU DB:", wx.DefaultPosition, wx.DefaultSize, 0 )
307 | self.m_staticText6.Wrap( -1 )
308 | fgSizer5.Add( self.m_staticText6, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
309 |
310 | bSizer5 = wx.BoxSizer( wx.HORIZONTAL )
311 |
312 | self.m_textCtrl_db_info = wx.TextCtrl( self, wx.ID_ANY, u"NA", wx.DefaultPosition, wx.Size( -1,25 ), wx.TE_CENTRE|wx.TE_READONLY )
313 | self.m_textCtrl_db_info.SetBackgroundColour( wx.Colour( 251, 210, 160 ) )
314 | self.m_textCtrl_db_info.Enable( False )
315 |
316 | bSizer5.Add( self.m_textCtrl_db_info, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
317 |
318 | self.m_gauge_status = wx.Gauge( self, wx.ID_ANY, 100, wx.DefaultPosition, wx.Size( -1,25 ), wx.GA_HORIZONTAL )
319 | self.m_gauge_status.SetValue( 0 )
320 | self.m_gauge_status.Enable( False )
321 |
322 | bSizer5.Add( self.m_gauge_status, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
323 |
324 | self.m_button_db_update = wx.Button( self, wx.ID_ANY, u"Update", wx.DefaultPosition, wx.DefaultSize, 0 )
325 | self.m_button_db_update.Enable( False )
326 |
327 | bSizer5.Add( self.m_button_db_update, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
328 |
329 |
330 | fgSizer5.Add( bSizer5, 1, wx.EXPAND, 5 )
331 |
332 |
333 | bSizer9.Add( fgSizer5, 1, wx.EXPAND|wx.TOP|wx.RIGHT|wx.LEFT, 5 )
334 |
335 | self.m_staticline3 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
336 | bSizer9.Add( self.m_staticline3, 0, wx.EXPAND|wx.BOTTOM|wx.RIGHT|wx.LEFT, 10 )
337 |
338 | m_sdbSizer2 = wx.StdDialogButtonSizer()
339 | self.m_sdbSizer2Cancel = wx.Button( self, wx.ID_CANCEL )
340 | m_sdbSizer2.AddButton( self.m_sdbSizer2Cancel )
341 | m_sdbSizer2.Realize();
342 |
343 | bSizer9.Add( m_sdbSizer2, 0, wx.ALIGN_RIGHT|wx.EXPAND|wx.BOTTOM|wx.RIGHT|wx.LEFT, 10 )
344 |
345 |
346 | self.SetSizer( bSizer9 )
347 | self.Layout()
348 |
349 | self.Centre( wx.BOTH )
350 |
351 | # Connect Events
352 | self.m_bt_jlink_path.Bind( wx.EVT_BUTTON, self.OnSelectDir )
353 | self.m_button_db_update.Bind( wx.EVT_BUTTON, self.OnUpdateDB )
354 |
355 | def __del__( self ):
356 | pass
357 |
358 |
359 | # Virtual event handlers, overide them in your derived class
360 | def OnSelectDir( self, event ):
361 | event.Skip()
362 |
363 | def OnUpdateDB( self, event ):
364 | event.Skip()
365 |
366 |
367 | ###########################################################################
368 | ## Class TargetDialog
369 | ###########################################################################
370 |
371 | class TargetDialog ( wx.Dialog ):
372 |
373 | def __init__( self, parent ):
374 | wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Supported Targets", pos = wx.DefaultPosition, size = wx.Size( 600,500 ), style = wx.DEFAULT_DIALOG_STYLE|wx.STAY_ON_TOP )
375 |
376 | self.SetSizeHintsSz( wx.Size( -1,-1 ), wx.DefaultSize )
377 |
378 | bSizer_main = wx.BoxSizer( wx.VERTICAL )
379 |
380 | self.m_splitter = wx.SplitterWindow( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.SP_3D|wx.SP_BORDER|wx.SP_LIVE_UPDATE )
381 | self.m_splitter.SetSashGravity( 1 )
382 | self.m_splitter.Bind( wx.EVT_IDLE, self.m_splitterOnIdle )
383 | self.m_splitter.SetMinimumPaneSize( 2 )
384 |
385 | self.m_panel_01 = wx.Panel( self.m_splitter, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
386 | fgSizer1 = wx.FlexGridSizer( 2, 1, 0, 0 )
387 | fgSizer1.AddGrowableCol( 0 )
388 | fgSizer1.AddGrowableRow( 1 )
389 | fgSizer1.SetFlexibleDirection( wx.BOTH )
390 | fgSizer1.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
391 |
392 | bSizer13 = wx.BoxSizer( wx.HORIZONTAL )
393 |
394 | self.m_staticText_vendor = wx.StaticText( self.m_panel_01, wx.ID_ANY, u"Manufacturer:", wx.DefaultPosition, wx.DefaultSize, 0 )
395 | self.m_staticText_vendor.Wrap( -1 )
396 | bSizer13.Add( self.m_staticText_vendor, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
397 |
398 | m_choice_vendorChoices = []
399 | self.m_choice_vendor = wx.Choice( self.m_panel_01, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice_vendorChoices, 0 )
400 | self.m_choice_vendor.SetSelection( 0 )
401 | bSizer13.Add( self.m_choice_vendor, 1, wx.ALL, 5 )
402 |
403 |
404 | bSizer13.AddSpacer( ( 20, 0), 0, wx.ALIGN_CENTER_VERTICAL, 5 )
405 |
406 | self.m_staticText_core = wx.StaticText( self.m_panel_01, wx.ID_ANY, u"MCU Core:", wx.DefaultPosition, wx.DefaultSize, 0 )
407 | self.m_staticText_core.Wrap( -1 )
408 | bSizer13.Add( self.m_staticText_core, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
409 |
410 | m_choice_coreChoices = []
411 | self.m_choice_core = wx.Choice( self.m_panel_01, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice_coreChoices, 0 )
412 | self.m_choice_core.SetSelection( 0 )
413 | bSizer13.Add( self.m_choice_core, 1, wx.ALL, 5 )
414 |
415 |
416 | fgSizer1.Add( bSizer13, 1, wx.EXPAND|wx.TOP, 8 )
417 |
418 | self.m_listCtrl_mcu_db = wx.ListCtrl( self.m_panel_01, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_AUTOARRANGE|wx.LC_NO_SORT_HEADER|wx.LC_REPORT )
419 | fgSizer1.Add( self.m_listCtrl_mcu_db, 1, wx.EXPAND|wx.ALL, 5 )
420 |
421 |
422 | self.m_panel_01.SetSizer( fgSizer1 )
423 | self.m_panel_01.Layout()
424 | fgSizer1.Fit( self.m_panel_01 )
425 | self.m_panel_02 = wx.Panel( self.m_splitter, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
426 | fgSizer2 = wx.FlexGridSizer( 1, 1, 0, 0 )
427 | fgSizer2.AddGrowableCol( 0 )
428 | fgSizer2.AddGrowableRow( 0 )
429 | fgSizer2.SetFlexibleDirection( wx.BOTH )
430 | fgSizer2.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
431 |
432 | self.m_listCtrl_usr_db = wx.ListCtrl( self.m_panel_02, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), wx.LC_AUTOARRANGE|wx.LC_REPORT )
433 | fgSizer2.Add( self.m_listCtrl_usr_db, 1, wx.EXPAND|wx.ALL, 5 )
434 |
435 |
436 | self.m_panel_02.SetSizer( fgSizer2 )
437 | self.m_panel_02.Layout()
438 | fgSizer2.Fit( self.m_panel_02 )
439 | self.m_splitter.SplitHorizontally( self.m_panel_01, self.m_panel_02, 280 )
440 | bSizer_main.Add( self.m_splitter, 1, wx.EXPAND|wx.RIGHT|wx.LEFT, 5 )
441 |
442 | self.m_staticline = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
443 | bSizer_main.Add( self.m_staticline, 0, wx.EXPAND|wx.RIGHT|wx.LEFT, 10 )
444 |
445 | m_sdbSizer = wx.StdDialogButtonSizer()
446 | self.m_sdbSizerOK = wx.Button( self, wx.ID_OK )
447 | m_sdbSizer.AddButton( self.m_sdbSizerOK )
448 | self.m_sdbSizerCancel = wx.Button( self, wx.ID_CANCEL )
449 | m_sdbSizer.AddButton( self.m_sdbSizerCancel )
450 | m_sdbSizer.Realize();
451 |
452 | bSizer_main.Add( m_sdbSizer, 0, wx.EXPAND|wx.ALL, 10 )
453 |
454 |
455 | self.SetSizer( bSizer_main )
456 | self.Layout()
457 |
458 | self.Centre( wx.BOTH )
459 |
460 | # Connect Events
461 | self.m_choice_vendor.Bind( wx.EVT_CHOICE, self.OnVendorChoice )
462 | self.m_choice_core.Bind( wx.EVT_CHOICE, self.OnCoreChoice )
463 | self.m_listCtrl_mcu_db.Bind( wx.EVT_LEFT_DCLICK, self.OnAdd )
464 | self.m_listCtrl_usr_db.Bind( wx.EVT_LEFT_DCLICK, self.OnDelete )
465 |
466 | def __del__( self ):
467 | pass
468 |
469 |
470 | # Virtual event handlers, overide them in your derived class
471 | def OnVendorChoice( self, event ):
472 | event.Skip()
473 |
474 | def OnCoreChoice( self, event ):
475 | event.Skip()
476 |
477 | def OnAdd( self, event ):
478 | event.Skip()
479 |
480 | def OnDelete( self, event ):
481 | event.Skip()
482 |
483 | def m_splitterOnIdle( self, event ):
484 | self.m_splitter.SetSashPosition( 280 )
485 | self.m_splitter.Unbind( wx.EVT_IDLE )
486 |
487 |
488 |
--------------------------------------------------------------------------------