From db84ce52c78d56642d70d61cbb5aa22cccf0c65a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcel=20St=C3=B6r?=
Date: Fri, 15 Sep 2017 21:27:08 +0200
Subject: [PATCH] Add flash mode 'dout'
Fixes #20
---
HtmlPopupTransientWindow.py | 30 +++++++++++++
Main.py | 44 ++++++++++++++++--
encode-bitmaps.py | 1 +
images.py | 87 ++++++++++++++++++++++++++++++++++++
images/info.png | Bin 0 -> 4487 bytes
5 files changed, 158 insertions(+), 4 deletions(-)
create mode 100644 HtmlPopupTransientWindow.py
create mode 100644 images/info.png
diff --git a/HtmlPopupTransientWindow.py b/HtmlPopupTransientWindow.py
new file mode 100644
index 0000000..0d06847
--- /dev/null
+++ b/HtmlPopupTransientWindow.py
@@ -0,0 +1,30 @@
+
+# coding=utf-8
+
+import wx
+import wx.html
+import webbrowser
+
+
+class HtmlPopupTransientWindow(wx.PopupTransientWindow):
+ def __init__(self, parent, style, html_body_content, bgcolor, size):
+ wx.PopupTransientWindow.__init__(self, parent, style)
+ panel = wx.Panel(self)
+ panel.SetBackgroundColour(bgcolor)
+
+ html_window = self.HtmlWindow(panel, wx.ID_ANY, size=size)
+ html_window.SetPage('' + html_body_content + '')
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(html_window, 0, wx.ALL, 5)
+ panel.SetSizer(sizer)
+
+ sizer.Fit(panel)
+ sizer.Fit(self)
+ self.Layout()
+
+ class HtmlWindow(wx.html.HtmlWindow):
+ def OnLinkClicked(self, link):
+ # get a hold of the PopupTransientWindow to close it
+ self.GetParent().GetParent().Dismiss()
+ webbrowser.open(link.GetHref())
\ No newline at end of file
diff --git a/Main.py b/Main.py
index dc85386..3617484 100644
--- a/Main.py
+++ b/Main.py
@@ -15,6 +15,20 @@ from esptool import NotImplementedInROMError
from argparse import Namespace
__version__ = "2.1"
+__flash_help__ = '''
+This setting is highly dependent on your device!
+
+ Details at http://bit.ly/2v5Rd32
+ and in the esptool
+ documentation
+
+ - Most ESP32 and ESP8266 ESP-12 use 'dio'.
+ - Most ESP8266 ESP-01/07 use 'qio'.
+ - ESP8285 requires 'dout'.
+
+
+'''
__supported_baud_rates__ = [9600, 57600, 74880, 115200, 230400, 460800, 921600]
# ---------------------------------------------------------------------------
@@ -95,7 +109,7 @@ class FlashConfig:
def __init__(self):
self.baud = 115200
self.erase_before_flash = False
- self.mode = "qio"
+ self.mode = "dio"
self.firmware_path = None
self.port = None
@@ -193,6 +207,7 @@ class NodeMcuFlasher(wx.Frame):
reload_button = wx.BitmapButton(panel, id=wx.ID_ANY, bitmap=bmp,
size=(bmp.GetWidth() + 7, bmp.GetHeight() + 7))
reload_button.Bind(wx.EVT_BUTTON, on_reload)
+ reload_button.SetToolTipString("Reload serial device list")
file_picker = wx.FilePickerCtrl(panel, style=wx.FLP_USE_TEXTCTRL)
file_picker.Bind(wx.EVT_FILEPICKER_CHANGED, on_pick_file)
@@ -228,8 +243,9 @@ class NodeMcuFlasher(wx.Frame):
sizer.Add(radio_button)
sizer.AddSpacer(10)
- add_flash_mode_radio_button(flashmode_boxsizer, 0, "qio", "Quad Flash I/O (qio)")
- add_flash_mode_radio_button(flashmode_boxsizer, 1, "dio", "Dual Flash I/O (dio), usually for >=4MB flash chips")
+ add_flash_mode_radio_button(flashmode_boxsizer, 0, "qio", "Quad I/O (qio)")
+ add_flash_mode_radio_button(flashmode_boxsizer, 1, "dio", "Dual I/O (dio)")
+ add_flash_mode_radio_button(flashmode_boxsizer, 2, "dout", "Dual Output (dout)")
erase_boxsizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -259,6 +275,26 @@ class NodeMcuFlasher(wx.Frame):
file_label = wx.StaticText(panel, label="NodeMCU firmware")
baud_label = wx.StaticText(panel, label="Baud rate")
flashmode_label = wx.StaticText(panel, label="Flash mode")
+
+ def on_info_hover(event):
+ from HtmlPopupTransientWindow import HtmlPopupTransientWindow
+ win = HtmlPopupTransientWindow(self, wx.SIMPLE_BORDER, __flash_help__, "#FFB6C1", (410, 140))
+
+ image = event.GetEventObject()
+ image_position = image.ClientToScreen((0, 0))
+ image_size = image.GetSize()
+ win.Position(image_position, (0, image_size[1]))
+
+ win.Popup()
+
+ icon = wx.StaticBitmap(panel, wx.ID_ANY, images.Info.GetBitmap())
+ icon.Bind(wx.EVT_MOTION, on_info_hover)
+
+ flashmode_label_boxsizer = wx.BoxSizer(wx.HORIZONTAL)
+ flashmode_label_boxsizer.Add(flashmode_label, 1, wx.EXPAND)
+ flashmode_label_boxsizer.AddStretchSpacer(0)
+ flashmode_label_boxsizer.Add(icon, 0, wx.ALIGN_RIGHT, 20)
+
erase_label = wx.StaticText(panel, label="Erase flash")
console_label = wx.StaticText(panel, label="Console")
@@ -266,7 +302,7 @@ class NodeMcuFlasher(wx.Frame):
port_label, (serial_boxsizer, 1, wx.EXPAND),
file_label, (file_picker, 1, wx.EXPAND),
baud_label, baud_boxsizer,
- flashmode_label, flashmode_boxsizer,
+ flashmode_label_boxsizer, flashmode_boxsizer,
erase_label, erase_boxsizer,
(wx.StaticText(panel, label="")), (button, 1, wx.EXPAND),
(console_label, 1, wx.EXPAND), (self.console_ctrl, 1, wx.EXPAND)])
diff --git a/encode-bitmaps.py b/encode-bitmaps.py
index b2cb5d9..ecdb227 100644
--- a/encode-bitmaps.py
+++ b/encode-bitmaps.py
@@ -10,6 +10,7 @@ command_lines = [
"-F -n Exit images/exit.png images.py",
"-a -F -n Reload images/reload.png images.py",
"-a -F -n Splash images/splash.png images.py",
+ "-a -F -n Info images/info.png images.py",
"-a -F -i -n Icon images/icon-256.png images.py",
]
diff --git a/images.py b/images.py
index 56e03f3..925dfc8 100644
--- a/images.py
+++ b/images.py
@@ -7606,6 +7606,93 @@ Splash = PyEmbeddedImage(
"OuPbk3NlUi8yrl/3VYFP7sMlU31aO8jWC1dyUeDftTTrOv6coEp+yK7/QzFrnT7WTSOBiWd8"
"DzjhI4F6KouFx5ME0tQbgfvfmHIzmcf7eP0AAAAASUVORK5CYII=")
+#----------------------------------------------------------------------
+Info = PyEmbeddedImage(
+ "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"
+ "2/WHDUwN4gyKDA4aPDCkGLoYphluMGwxHDTSM5psNN+ozuiusYKxi3GG8SbjVuP3JqYmCSbL"
+ "TRpNnptqmIaYFprWmd43o5l5meWZVZvdMCeau5hnmW8177BALRwtMiyqLK5ZopZOlnzLrZad"
+ "EwgTXCcIJlRP6LaiWvlYFVjVWfVaM63DrYusG61fTjSamDxx3cTWiV9tHG2ybXbb3LNVtQ21"
+ "LbJttn1tZ2HHsauyu2FPsw+0X2TfZP/KwdKB57DN4bYjw3Gy43LHFscvTs5OQqd6p35nI+cU"
+ "5y3O3S5qLlEuq1wuuRJcfV0XuZ5w/ejm5JbvdtjtL3cr9yz3fe7PJ5lO4k3aPemxh4EH22On"
+ "R48nyzPFc4dnj5e+F9ur2uuRt6E313uP9zMfc59Mn/0+L31tfIW+x3zf+7n5LfA744/5B/mX"
+ "+LcHqAbEBVQGPAw0CEwPrAscDHIMmhd0JpgQHBa8Lrg7RCeEE1IbMhjqHLog9HwYNSwmrDLs"
+ "UbhFuDC8eTI6OXTy+sn3I4wjBBGNkSAyJHJ95IMo06i8qN+mEKdETama8jTaNnp+dGsMI2Zm"
+ "zL6Yd7G+sWti78WZxYnjWuKV4qfF18a/T/BPKEvoSZyYuCDxapJWEj+pKZmUHJ+8J3loasDU"
+ "jVP7pjlOK552a7rp9DnTL8/QmpE94+RMpZnsmUdSCCkJKftSPrMj2dXsodSQ1C2pgxw/zibO"
+ "C643dwO3n+fBK+M9S/NIK0t7nu6Rvj69P8MrozxjgO/Hr+S/ygzO3J75Pisya2/WSHZC9sEc"
+ "ck5KznGBqiBLcH6W7qw5szpzLXOLc3vy3PI25g0Kw4R7RIhouqgpXw0ec9rEZuKfxL0FngVV"
+ "BR9mx88+MkdljmBO21yLuSvnPisMLPxlHj6PM69lvv78JfN7F/gs2LkQWZi6sGWR4aJli/oW"
+ "By2uWUJZkrXk9yKborKit0sTljYv01m2eNnjn4J+qiumFwuLu5e7L9++Al/BX9G+0n7l5pVf"
+ "S7glV0ptSstLP6/irLrys+3PFT+PrE5b3b7Gac22tcS1grW31nmtqylTKSsse7x+8vqGDawN"
+ "JRvebpy58XK5Q/n2TZRN4k09FeEVTZuNNq/d/Lkyo/JmlW/VwS3aW1Zueb+Vu7Vrm/e2+u06"
+ "20u3f9rB33F7Z9DOhmqT6vJdxF0Fu57ujt/d+ovLL7V7tPaU7vmyV7C3pya65nytc23tPu19"
+ "a+rQOnFd//5p+zsO+B9oqreq33mQebD0EDgkPvTHrym/3jocdrjliMuR+qPGR7ccYxwraUAa"
+ "5jYMNmY09jQlNXUeDz3e0uzefOw369/2ntA/UXVS/eSaU5RTy06NnC48PXQm98zA2fSzj1tm"
+ "ttw7l3juxvkp59svhF24dDHw4rlWn9bTlzwunbjsdvn4FZcrjVedrja0ObYd+93x92PtTu0N"
+ "15yvNXW4djR3Tuo81eXVdfa6//WLN0JuXL0ZcbPzVtyt293Tuntuc28/v5N959XdgrvD9xbf"
+ "J9wveaD8oPyh9sPqf5j/42CPU8/JXv/etkcxj+495jx+8UT05HPfsqe0p+XP9J7VPrd7fqI/"
+ "sL/jj6l/9L3IfTE8UPynyp9bXpq9PPqX919tg4mDfa+Er0Zer3qj+WbvW4e3LUNRQw/f5bwb"
+ "fl/yQfNDzUeXj62fEj49G579mfS54ov5l+avYV/vj+SMjOSyhWzpUQCDDU1LA+D1XgBoSfDs"
+ "0AEAhS67e0kFkd0XpQj8Jyy7n0nFCYC93gDELQYgHJ5RtsFmDDEV9pKjd6w3QO3tx5pcRGn2"
+ "drJYVHiDIXwYGXmjAwCpGYAvwpGR4a0jI192Q7J3ADiTJ7vzSYQIz/c7JPdJ0NatDH6UfwI5"
+ "m2viYAPWEQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAdVpVFh0WE1MOmNvbS5hZG9iZS54bXAA"
+ "AAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBD"
+ "b3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8x"
+ "OTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6"
+ "YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90"
+ "aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpDb21wcmVzc2lvbj4xPC90aWZmOkNvbXByZXNz"
+ "aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgog"
+ "ICAgICAgICA8dGlmZjpQaG90b21ldHJpY0ludGVycHJldGF0aW9uPjI8L3RpZmY6UGhvdG9t"
+ "ZXRyaWNJbnRlcnByZXRhdGlvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRm"
+ "OlJERj4KPC94OnhtcG1ldGE+CgLYgAUAAAM2SURBVDgRTVNNaBtHFP5mdle2JFvIazsiiWMj"
+ "G2KcprekuMQBhbbk4uJTpEMPgVwKLQ7kGApucushIZe2h97TUgUaCiEtKL5E9Bw3OAmuhUMc"
+ "2LYrGUn1alfen3l9oyTggWFm3sz73nvffA84NOjSJePQUW+HeWYO2+jGDXn4LN4dtLO4dy/5"
+ "DMh9df58OXv69MfDk5PT0jBk4HmO5ziP1123ulqrOQQIEEEIQQOAd85/AGdnL1/+bnJh4axh"
+ "24BSQCoFjIwAvg9nZ6ex3eutlW7f/kkHJiIhqhy5zJG188KVKw/H5ucnQiDRt/LMGQgN0miQ"
+ "HB0VIpUy93Z2sBlFX5bW1r7nTKTUzqucdnF5+duxI0cm/E7nIGo2DWVZplkqmfLcOTMJAiva"
+ "2zPj/f1o/OhRFIm++fXu3QucvjJ1Kp8X5ypjtv2B1+kmMI0U4yJ++hT9+/chuFbqdCByOSTd"
+ "riUzmWg6lxt1HecaZ1kfAAwXJj+ykgRhP1AUhoYsFpGqVCDiGNTvg9JpULcLwWuklGFx0HwY"
+ "Lv5Yr58yPwTSJtFMzCQlpik0q8p1ofb3kb54EcTA/safQLvN1DP9USyUFJRSys4GwSnzfbap"
+ "OJaq14Pi1IVm/PlzHHDqQ0tLEGxTgT/4BTHMsjBCwWJRNDRkSClH5Q98FRI58DxQEJDilQGB"
+ "iQnNMZhpEJ8Tbecg5PuUdDriwLJC5HLNgapC2358oB/4vlRhiGRrC3Gj8UYHnEny6hWo1YJi"
+ "PkS/ryIG6BYKLo4dezYAeLmy8vNePr891O0aanc3EsvLGLl5EzKbBbOOzPXroPl5qHab6PVr"
+ "1Zmagjc7+/DTEye2ZZWrWlldddxS6ev28eMwGw2L2Y/iZlN5tRp5jx5R7LrEtkSur8d+Pm/t"
+ "Li7+FU1P3+HqBkMMtM3b+q1bX7yoVP5rptP0N5fOU/3DqvxXf4xt08urV6lerW7VNjaWtKcW"
+ "65te0JrmxtDG3x88uGBvbl7LtlqLpueNcceY0fh42Juacr25ud/UzMydT06efFGtVo1yuZwM"
+ "AN6iCd1ebFAMbf7y5Ml7ac9b4C8biTOZVlIoPNM1v30r+SU3CfA/ZNahIBhUgOQAAAAASUVO"
+ "RK5CYII=")
+
#----------------------------------------------------------------------
Icon = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAAXNSR0IArs4c6QAAACBjSFJN"
diff --git a/images/info.png b/images/info.png
new file mode 100644
index 0000000000000000000000000000000000000000..5dfc80a23970a3c1bdc7fb450fbb9ac9d23cfe07
GIT binary patch
literal 4487
zcmZ`+2T)U6yA9Gy0O=(N(rZGmA=E2GdXcIiE%X3MXi}tzQjJJ27ZeZ>LhqmyK~d>d
zkZPy~=}oE+@4fH-@4cC~XZAk(ti8UqzVF*JXXeBi8|nb5IH&*s01&RLZF=>j|2-+l
zu2$~-Uk(5O4U4;$mN8sQi^mw{gK+n90RVL4(k#iX%s#Q?*_u+og(E3+Dc@3#mLJ%W
z6h$XJBcTw`)HJRsOrWYHWxkGE7mY3OByz5>s;;K6s#Y^Lv9@NVmN%a-im0p#+YVir
zJ=xAe51zYjwd@Z7UO0CT4h-B%Bl>uKnYu7K)H)9SN!%3DNp$^11l79NQ{gW{qM{&m
z_RU}5Z6uNQsD0D(p3^V8zeGjv=EV{N7)bp@Eqgvi{uBl@lL=X7(g9uq2|(Aiwc9&9
zJsz66^Z;IP*LP{$&92wdPz?`8&Q0jTu}
zGB&x%YUF$L{VZ~^pqZK&Q+qe;t(|=>#}&mpieff5xFzVFbsqIC;XW?LB;viHChGmA
z1{`XVB#u_@>m%
!3$k
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
Cxjl{m
literal 0
HcmV?d00001