Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
1gitclub committed Jul 14, 2015
1 parent b26b81f commit c648ed9
Show file tree
Hide file tree
Showing 47 changed files with 38,358 additions and 2 deletions.
Empty file added .gitignore
Empty file.
136 changes: 136 additions & 0 deletions ArduloaderWindow.py
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)

37 changes: 37 additions & 0 deletions BoardHelper.py
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)
86 changes: 86 additions & 0 deletions ConfigHelper.py
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()

44 changes: 44 additions & 0 deletions PortManager.py
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()

11 changes: 9 additions & 2 deletions README.md
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)

72 changes: 72 additions & 0 deletions Ui_MainWindow.py
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))

Loading

0 comments on commit c648ed9

Please sign in to comment.