-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
47 changed files
with
38,358 additions
and
2 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#-*- coding: utf-8 -*- | ||
from os import path as OSPath | ||
from Ui_MainWindow import Ui_MainWindow | ||
from Uploader import Uploader | ||
from PortManager import PortManager | ||
from ConfigHelper import ConfigHelper | ||
from icons import * | ||
import const | ||
import BoardHelper | ||
|
||
from PyQt4.QtGui import QMainWindow | ||
from PyQt4.QtGui import QPixmap, QBitmap | ||
from PyQt4.QtGui import QPainter | ||
from PyQt4.QtGui import QColor | ||
from PyQt4 import QtGui | ||
from PyQt4 import QtCore | ||
|
||
tostr = lambda qstr: qstr.toUtf8().data() | ||
togbk = lambda qstr: unicode(tostr(qstr), "utf-8").encode("gbk") | ||
|
||
class ArduloaderWindow(QMainWindow): | ||
def __init__(self, parent=None): | ||
QMainWindow.__init__(self) | ||
|
||
self.ui = Ui_MainWindow() | ||
self.ui.setupUi(self) | ||
self.portManager = PortManager(self.ui, startmonitor=True) | ||
self.configHelper = ConfigHelper(self.ui) | ||
self.initSignal() | ||
self.setupUi_Ex() | ||
|
||
def setupUi_Ex(self): | ||
self.setWindowTitle(const.windowtitle) | ||
self.ui.textEdit.append(const.aboutinfo) | ||
self.ui.headLabel.setPixmap(QPixmap(":/main/icons/main/arduloader.png")) | ||
self.setWindowIcon(QtGui.QIcon(":/main/icons/main/logo.png")) | ||
self.setBoards() | ||
|
||
self.configHelper.updateUiByConfig() | ||
|
||
def setBoards(self): | ||
ret, self.__boardsinfodict = BoardHelper.getBoardsInfo() | ||
if not ret: | ||
self.__boardsinfodict = {} | ||
return | ||
|
||
for boardname in self.__boardsinfodict.keys(): | ||
self.ui.mcuCombox.addItem(boardname) | ||
|
||
def onUploadFinish(self, ret, text): | ||
self.timer.stop() | ||
try: | ||
res = ret == 0 and "Upload SUCCESS:)" or ("%s\nUpload FAILED:(" % text) | ||
except IOError: | ||
res = "Read tmp file error" | ||
except: | ||
res = "Unknown error" | ||
|
||
self.ui.textEdit.append(res) | ||
|
||
def onUploading(self): | ||
prev_cursor = self.ui.textEdit.textCursor() | ||
self.ui.textEdit.moveCursor(QtGui.QTextCursor.End) | ||
self.ui.textEdit.insertPlainText (".") | ||
self.ui.textEdit.setTextCursor(prev_cursor) | ||
|
||
def getUploadArgs(self): | ||
infodict = self.__boardsinfodict.get(tostr(self.ui.mcuCombox.currentText())) | ||
if not infodict: | ||
return | ||
|
||
mcu = infodict["mcu"] | ||
speed = infodict["speed"] | ||
protocol = infodict["protocol"] | ||
maximum_size = infodict["maximum_size"] | ||
comport = tostr(self.ui.portCombox.currentText()) | ||
flash_bin = togbk(self.ui.hexfileCombox.currentText()) | ||
|
||
return {"mcu": mcu, | ||
"speed": speed, | ||
"protocol": protocol, | ||
"maximum_size": maximum_size, | ||
"comport": comport, | ||
"flash_bin": flash_bin | ||
} | ||
|
||
def checkUploadArgs(self, argsdict): | ||
if not argsdict: | ||
self.ui.textEdit.append("Get chip data error") | ||
return False | ||
|
||
if not OSPath.exists(argsdict.get("flash_bin", "")): | ||
self.ui.textEdit.append("Hex file not exists") | ||
return False | ||
|
||
# TODO: 检查文件大小是否超多当前芯片允许的最大值 | ||
return True | ||
|
||
def startUpload(self): | ||
argsdict = self.getUploadArgs() | ||
if not self.checkUploadArgs(argsdict): | ||
return | ||
|
||
self.uploader = Uploader() | ||
self.connect(self.uploader.qobj, QtCore.SIGNAL(const.finish_sig), self.onUploadFinish) | ||
self.uploader.resetUploadArgs(argsdict) | ||
|
||
self.ui.textEdit.clear() | ||
self.ui.textEdit.append("Start uploading\n") | ||
self.timer = QtCore.QTimer() | ||
self.timer.timeout.connect(self.onUploading) | ||
self.uploader.start() | ||
self.timer.start(const.process_interval) | ||
|
||
def onOpenHexFile(self): | ||
filename = QtGui.QFileDialog.getOpenFileName(self, "Choose a HEX file", ".", "HEX (*.hex)") | ||
if filename == "": | ||
return | ||
index = self.ui.hexfileCombox.findText(filename) | ||
if index < 0: | ||
self.ui.hexfileCombox.insertItem(0, filename) | ||
index = 0 | ||
self.ui.hexfileCombox.setCurrentIndex(index) | ||
|
||
def closeEvent(self, e): | ||
hex = tostr(self.ui.hexfileCombox.currentText()) | ||
com = tostr(self.ui.portCombox.currentText()) | ||
board = tostr(self.ui.mcuCombox.currentText()) | ||
self.configHelper.updateConfig(hex, com, board) | ||
e.accept() | ||
|
||
def initSignal(self): | ||
self.ui.exitButton.clicked.connect(self.close) | ||
self.ui.uploadButton.clicked.connect(self.startUpload) | ||
self.ui.openHexButton.clicked.connect(self.onOpenHexFile) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#-*- coding: utf-8 -*- | ||
import const | ||
from re import search as ReSearch | ||
|
||
def __parseBoards(fp): | ||
boardsinfo = {} | ||
cur_board_name = "" | ||
for line in fp.readlines(): | ||
line = line.strip() | ||
if line == '' or line.startswith('#'): | ||
continue | ||
value = line.split("=")[-1] | ||
if ReSearch(const.boards_name_matcher, line): | ||
cur_board_name = value | ||
boardsinfo[cur_board_name] = {} | ||
if cur_board_name == "": | ||
continue | ||
|
||
if ReSearch(const.boards_upload_protocol_matcher, line): | ||
boardsinfo[cur_board_name]["protocol"] = value | ||
if ReSearch(const.boards_upload_maximum_size_matcher, line): | ||
boardsinfo[cur_board_name]["maximum_size"] = int(value) | ||
if ReSearch(const.boards_upload_speed_matcher, line): | ||
boardsinfo[cur_board_name]["speed"] = value | ||
if ReSearch(const.boards_mcu_matcher, line): | ||
boardsinfo[cur_board_name]["mcu"] = value | ||
|
||
return boardsinfo | ||
|
||
def getBoardsInfo(): | ||
try: | ||
fp = open(const.boards_txt, "r") | ||
boardsinfo = __parseBoards(fp) | ||
fp.close() | ||
return True, boardsinfo | ||
except Exception, e: | ||
return False, repr(e) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#-*- coding: utf-8 -*- | ||
import const | ||
from ConfigParser import ConfigParser | ||
|
||
class ConfigHelper: | ||
SEC_UPLOAD = "upload" | ||
SEC_UI = "ui" | ||
KEY_HEX = "hex" | ||
KEY_COM = "port" | ||
KEY_BOARD = "board" | ||
KEY_STYLE = "style" | ||
KEY_PROGPAPER = "progpaper" | ||
|
||
def __init__(self, ui, cfgini=const.config): | ||
self.ui = ui | ||
self.cfgini = cfgini | ||
self.cfg = ConfigParser() | ||
self.readCfg() | ||
|
||
def readCfg(self): | ||
return len(self.cfg.read(self.cfgini)) > 0 | ||
|
||
def getVal(self, section, key): | ||
if not self.cfg.has_section(section): | ||
return "" | ||
if not self.cfg.has_option(section, key): | ||
return "" | ||
|
||
return self.cfg.get(section, key).strip() | ||
|
||
def setVal(self, section, key, val): | ||
if not self.cfg.has_section(section): | ||
self.cfg.add_section(section) | ||
|
||
self.cfg.set(section, key, val) | ||
|
||
def writeCfg(self): | ||
try: | ||
self.cfg.write(open(self.cfgini, "w")) | ||
except IOError: | ||
pass | ||
|
||
def __updateUiAboutUpload(self): | ||
hex = self.getVal(self.SEC_UPLOAD, self.KEY_HEX) | ||
if hex != "": | ||
self.ui.hexfileCombox.addItem(hex) | ||
|
||
board = self.getVal(self.SEC_UPLOAD, self.KEY_BOARD) | ||
if board != "": | ||
index = self.ui.mcuCombox.findText(board) | ||
if index != -1: | ||
self.ui.mcuCombox.setCurrentIndex(index) | ||
|
||
com = self.getVal(self.SEC_UPLOAD, self.KEY_COM) | ||
if com != "": | ||
index = self.ui.portCombox.findText(com) | ||
if index != -1: | ||
self.ui.portCombox.setCurrentIndex(index) | ||
else: | ||
self.ui.portCombox.addItem(com) | ||
self.ui.portCombox.setCurrentIndex(self.ui.portCombox.count() - 1) | ||
|
||
def __updateUiAboutUi(self): | ||
style = self.getVal(self.SEC_UI, self.KEY_STYLE) | ||
if style != "": | ||
from PyQt4.QtGui import QApplication | ||
QApplication.setStyle(style) | ||
|
||
progpaper = self.getVal(self.SEC_UI, self.KEY_PROGPAPER) | ||
if progpaper != "": | ||
from os import path as OSPath | ||
from PyQt4.QtGui import QPixmap | ||
progpaper = unicode(progpaper, "gbk") | ||
if OSPath.exists(progpaper): | ||
self.ui.headLabel.setPixmap(QPixmap(progpaper).scaled(const.width, const.height)) | ||
|
||
def updateUiByConfig(self): | ||
self.__updateUiAboutUpload() | ||
self.__updateUiAboutUi() | ||
|
||
def updateConfig(self, hex="", com="", board=""): | ||
self.setVal(self.SEC_UPLOAD, self.KEY_HEX, hex) | ||
self.setVal(self.SEC_UPLOAD, self.KEY_COM, com) | ||
self.setVal(self.SEC_UPLOAD, self.KEY_BOARD, board) | ||
self.writeCfg() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#-*- coding: utf-8 -*- | ||
import serial.tools.list_ports as lp | ||
from PyQt4.QtCore import QTimer | ||
|
||
class PortManager(object): | ||
def __init__(self, ui, queryinterval=1000, startmonitor=False): | ||
self.ui = ui | ||
self.queryinterval = queryinterval | ||
self.querytimer = QTimer() | ||
self.querytimer.timeout.connect(self.__updateUiComPorts) | ||
self.com_list = [] | ||
self.__updateUiComPorts(showmsg=False) | ||
if startmonitor: | ||
self.startComPortMonitor() | ||
|
||
def __updateUiComPorts(self, com_list=None, showmsg=True): | ||
if com_list is None: | ||
com_list = self.__getComInfoList() | ||
|
||
# NEW ADDED | ||
for comport in list(set(com_list) - set(self.com_list)): | ||
self.ui.portCombox.addItem(comport) | ||
if showmsg: | ||
self.ui.textEdit.append("New port found: %s" % comport) | ||
# NEW REMOVED | ||
for comport in list(set(self.com_list) - set(com_list)): | ||
index = self.ui.portCombox.findText(comport) | ||
if index == -1: | ||
continue | ||
self.ui.portCombox.removeItem(index) | ||
if showmsg: | ||
self.ui.textEdit.append("Port removed: %s" % comport) | ||
|
||
self.com_list = com_list | ||
|
||
def __getComInfoList(self): | ||
return [tup[0] for tup in list(lp.comports())] | ||
|
||
def startComPortMonitor(self): | ||
self.querytimer.start(self.queryinterval) | ||
|
||
def stopComPortMonitor(self): | ||
self.querytimer.stop() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,13 @@ | ||
#Arduloader | ||
|
||
Arduloader is tool for uploading hex file to your Arduino board. | ||
It's implemented by Python. | ||
|
||
These development env is required: | ||
- You can build exe file on Windows like this: python buildexe.py py2exe | ||
|
||
|
||
Dependences: | ||
1. Python | ||
1. PyQt4 | ||
2. Py2exe | ||
2. Py2exe(build exe file on Windows) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
# Form implementation generated from reading ui file '../ui/mainwindow.ui' | ||
# | ||
# Created: Tue Jul 14 22:43:58 2015 | ||
# by: PyQt4 UI code generator 4.9.5 | ||
# | ||
# WARNING! All changes made in this file will be lost! | ||
|
||
from PyQt4 import QtCore, QtGui | ||
|
||
try: | ||
_fromUtf8 = QtCore.QString.fromUtf8 | ||
except AttributeError: | ||
_fromUtf8 = lambda s: s | ||
|
||
class Ui_MainWindow(object): | ||
def setupUi(self, MainWindow): | ||
MainWindow.setObjectName(_fromUtf8("MainWindow")) | ||
MainWindow.resize(447, 556) | ||
self.centralwidget = QtGui.QWidget(MainWindow) | ||
self.centralwidget.setObjectName(_fromUtf8("centralwidget")) | ||
self.gridLayout = QtGui.QGridLayout(self.centralwidget) | ||
self.gridLayout.setObjectName(_fromUtf8("gridLayout")) | ||
self.headLabel = QtGui.QLabel(self.centralwidget) | ||
self.headLabel.setText(_fromUtf8("")) | ||
self.headLabel.setObjectName(_fromUtf8("headLabel")) | ||
self.gridLayout.addWidget(self.headLabel, 0, 0, 1, 5) | ||
self.horizontalLayout = QtGui.QHBoxLayout() | ||
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) | ||
self.hexfileCombox = QtGui.QComboBox(self.centralwidget) | ||
self.hexfileCombox.setMinimumSize(QtCore.QSize(311, 0)) | ||
self.hexfileCombox.setEditable(True) | ||
self.hexfileCombox.setObjectName(_fromUtf8("hexfileCombox")) | ||
self.horizontalLayout.addWidget(self.hexfileCombox) | ||
self.openHexButton = QtGui.QPushButton(self.centralwidget) | ||
self.openHexButton.setObjectName(_fromUtf8("openHexButton")) | ||
self.horizontalLayout.addWidget(self.openHexButton) | ||
self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 5) | ||
self.portCombox = QtGui.QComboBox(self.centralwidget) | ||
self.portCombox.setEditable(False) | ||
self.portCombox.setObjectName(_fromUtf8("portCombox")) | ||
self.gridLayout.addWidget(self.portCombox, 2, 0, 1, 1) | ||
self.textEdit = QtGui.QTextEdit(self.centralwidget) | ||
self.textEdit.setStyleSheet(_fromUtf8("")) | ||
self.textEdit.setFrameShape(QtGui.QFrame.NoFrame) | ||
self.textEdit.setObjectName(_fromUtf8("textEdit")) | ||
self.gridLayout.addWidget(self.textEdit, 3, 0, 1, 5) | ||
spacerItem = QtGui.QSpacerItem(260, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) | ||
self.gridLayout.addItem(spacerItem, 4, 0, 1, 3) | ||
self.uploadButton = QtGui.QPushButton(self.centralwidget) | ||
self.uploadButton.setObjectName(_fromUtf8("uploadButton")) | ||
self.gridLayout.addWidget(self.uploadButton, 4, 3, 1, 1) | ||
self.exitButton = QtGui.QPushButton(self.centralwidget) | ||
self.exitButton.setObjectName(_fromUtf8("exitButton")) | ||
self.gridLayout.addWidget(self.exitButton, 4, 4, 1, 1) | ||
self.mcuCombox = QtGui.QComboBox(self.centralwidget) | ||
self.mcuCombox.setEnabled(True) | ||
self.mcuCombox.setEditable(False) | ||
self.mcuCombox.setObjectName(_fromUtf8("mcuCombox")) | ||
self.gridLayout.addWidget(self.mcuCombox, 2, 1, 1, 4) | ||
MainWindow.setCentralWidget(self.centralwidget) | ||
|
||
self.retranslateUi(MainWindow) | ||
QtCore.QMetaObject.connectSlotsByName(MainWindow) | ||
|
||
def retranslateUi(self, MainWindow): | ||
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Arduloader", None, QtGui.QApplication.UnicodeUTF8)) | ||
self.openHexButton.setText(QtGui.QApplication.translate("MainWindow", "Browser", None, QtGui.QApplication.UnicodeUTF8)) | ||
self.uploadButton.setText(QtGui.QApplication.translate("MainWindow", "Upload", None, QtGui.QApplication.UnicodeUTF8)) | ||
self.exitButton.setText(QtGui.QApplication.translate("MainWindow", "Exit", None, QtGui.QApplication.UnicodeUTF8)) | ||
|
Oops, something went wrong.