Use built-in Python DFU-util

This commit is contained in:
iabdalkader 2014-10-03 03:33:00 +02:00
parent 0573d0726d
commit 4bb1d3fc3f
3 changed files with 84 additions and 50 deletions

View File

@ -55,6 +55,7 @@
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Update Firmware</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
@ -107,12 +108,15 @@
</packing>
</child>
<child>
<object class="GtkSpinner" id="fw_spinner">
<object class="GtkProgressBar" id="fw_progressbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_text">True</property>
<property name="text" translatable="yes"> </property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>

View File

@ -1,28 +1,30 @@
#!/usr/bin/env python
import pydfu
import openmv
import sys, os, os.path
import gtk
import gtksourceview2 as gtksourceview
from time import sleep
import gtk, gtksourceview2 as gtksourceview
import gio
import pango
import gobject
import vte
import serial
from time import sleep
import usb.core
import usb.util
import numpy as np
import openmv
from os.path import expanduser
import subprocess
UI_PATH =os.path.dirname(os.path.realpath(__file__))+"/openmv-ide.glade"
CONFIG_PATH = expanduser("~")+"/.openmvide.config"
EXAMPLE_PATH = os.path.dirname(os.path.realpath(__file__))+"/examples"
SCRIPTS_PATH = os.path.dirname(os.path.realpath(__file__))+"/scripts"
FWBIN_PATH = ""
FWBIN_PATH = "/home/mux/src/c/stm32f4/openmv/src/build/openmv.bin"
DFU_CMD = "dfu-util -d 0483:df11 -c 1 -i 0 -a 0 -s 0x08000000 -D %s"
SCALE =1
flash_offsets= [0x08000000, 0x08004000, 0x08008000, 0x0800C000,
0x08010000, 0x08020000, 0x08040000, 0x08060000,
0x08080000, 0x080A0000, 0x080C0000, 0x080E0000]
class OMVGtk:
def __init__(self):
@ -146,6 +148,11 @@ class OMVGtk:
message.run()
message.destroy()
def refresh_gui(self, delay=0.0001, wait=0.0001):
sleep(delay)
gtk.main_iteration_do(block=False)
sleep(wait)
def connect(self):
self.terminal = self.builder.get_object('terminal')
try:
@ -218,16 +225,54 @@ class OMVGtk:
dialog.destroy()
# Fake multitasking :P
def fwupdate_task(self, state):
if (state["init"]):
pydfu.init()
state["init"]=False
state["erase"]=True
state["bar"].set_text("Erasing...")
return True
elif (state["erase"]):
page = state["page"]
total = len(flash_offsets)
pydfu.page_erase(flash_offsets[page])
page +=1
state["bar"].set_fraction(page/float(total))
if (page == total):
state["erase"] = False
state["write"] = True
state["bar"].set_text("Uploading...")
state["page"] = page
return True
elif (state["write"]):
buf = state["buf"]
xfer_bytes = state["xfer_bytes"]
xfer_total = state["xfer_total"]
# Send chunk
chunk = min (64, xfer_total-xfer_bytes)
pydfu.write_page(buf[xfer_bytes:xfer_bytes+chunk], xfer_bytes)
xfer_bytes += chunk
state["xfer_bytes"] = xfer_bytes
state["bar"].set_fraction(xfer_bytes/float(xfer_total))
if (xfer_bytes == xfer_total):
pydfu.exit_dfu()
state["dialog"].hide()
return False
return True
def fwupdate_clicked(self, widget):
if (self.connected):
dialog = self.builder.get_object("fw_dialog")
fw_entry = self.builder.get_object("fw_entry")
spinner = self.builder.get_object("fw_spinner")
fw_progress = self.builder.get_object("fw_progressbar")
ok_button = self.builder.get_object("fw_ok_button")
cancel_button = self.builder.get_object("fw_cancel_button")
spinner.stop()
spinner.set_visible(False)
ok_button.set_sensitive(True)
cancel_button.set_sensitive(True)
dialog.set_transient_for(self.window);
@ -238,24 +283,24 @@ class OMVGtk:
if dialog.run() == gtk.RESPONSE_OK:
ok_button.set_sensitive(False)
cancel_button.set_sensitive(False)
spinner.set_visible(True)
spinner.start()
fw_progress.set_text("")
fw_progress.set_fraction(0.0)
with open(fw_entry.get_text(), 'r') as f:
buf= f.read()
state={"init":True, "erase":False, "write":False,
"page":0, "buf":buf, "bar":fw_progress, "dialog":dialog,
"xfer_bytes":0, "xfer_total":len(buf)}
# call dfu-util
openmv.enter_dfu()
sleep(1.0)
gobject.gobject.idle_add(self.fwupdate_task, state);
dfu_util = subprocess.Popen(DFU_CMD%fw_entry.get_text(), shell=True, stdout=subprocess.PIPE)
while dfu_util.poll() == None and gtk.events_pending():
gtk.main_iteration()
if (dfu_util.returncode):
self.show_message_dialog(gtk.MESSAGE_ERROR, "Failed to update firmware\n")
openmv.exit_dfu()
dialog.hide()
# try:
# except Exception as e:
# self.show_message_dialog(gtk.MESSAGE_ERROR, "Failed to update firmware%s"%(e))
def reset_clicked(self, widget):
if (self.connected):

View File

@ -1,14 +1,20 @@
#!/usr/bin/env python
import sys
# This file is part of the OpenMV project.
# Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
# This work is licensed under the MIT license, see the file LICENSE for details.
#
# Openmv module.
import struct
import sys,time
import usb.core
import usb.util
import struct
import pydfu
import numpy as np
from PIL import Image
import time
import StringIO
__dev = None
# VID/PID
__VID=0xf055
__PID=0x9800
@ -59,7 +65,6 @@ def init():
__dev.set_interface_altsetting(__INTERFACE, __ALTSETTING)
def release():
global __dev
try:
# Release device
usb.util.dispose_resources(dev)
@ -83,20 +88,16 @@ def fb_to_arr(buff, bpp):
return np.column_stack((r,g,b))
def fb_size():
global __dev
# read fb header
buf = __dev.ctrl_transfer(0xC1, __USBDBG_FRAME_SIZE, 0, __INTERFACE, __FB_HDR_SIZE, __TIMEOUT)
size = struct.unpack("III", buf)
return size
def fb_lock():
global __dev
buf = __dev.ctrl_transfer(0xC1, __USBDBG_FRAME_LOCK, 0, __INTERFACE, 1, __TIMEOUT)
return struct.unpack("B", buf)[0]
def fb_dump():
global __dev
if (fb_lock() == 0):
return None
@ -161,22 +162,6 @@ def enter_dfu():
except:
pass
#See app note AN3156
def exit_dfu():
timeout = 1000
dev = usb.core.find(idVendor=0x0483, idProduct=0xdf11)
# Claim DFU interface
usb.util.claim_interface(dev, 0)
# Send DNLOAD with 0 length to exit DFU
dev.ctrl_transfer(0x21, 0x01, 0, 0, None, timeout)
# Execute last command
dev.ctrl_transfer(0xA1, 0x03, 0, 0, 6, timeout)
# Release device
usb.util.dispose_resources(dev)
def reset():
try:
# This will timeout.