From 0573d0726dea67a6a9572b861d51ff8fa8170362 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 3 Oct 2014 03:32:20 +0200 Subject: [PATCH] Add Python DFU Util --- usr/pydfu.py | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100755 usr/pydfu.py diff --git a/usr/pydfu.py b/usr/pydfu.py new file mode 100755 index 000000000..bb22be777 --- /dev/null +++ b/usr/pydfu.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python +# This file is part of the OpenMV project. +# Copyright (c) 2013/2014 Ibrahim Abdelkader +# This work is licensed under the MIT license, see the file LICENSE for details. +# +# DFU util. +# See app note AN3156. + +import struct +import sys,time +import usb.core +import usb.util +import argparse + +# VID/PID +__VID=0x0483 +__PID=0xdf11 + +# USB request __TIMEOUT +__TIMEOUT = 4000 + +# DFU commands +__DFU_DETACH = 0 +__DFU_DNLOAD = 1 +__DFU_UPLOAD = 2 +__DFU_GETSTATUS = 3 +__DFU_CLRSTATUS = 4 +__DFU_GETSTATE = 5 +__DFU_ABORT = 6 + +# DFU status +__DFU_STATE_APP_IDLE = 0x00 +__DFU_STATE_APP_DETACH = 0x01 +__DFU_STATE_DFU_IDLE = 0x02 +__DFU_STATE_DFU_DOWNLOAD_SYNC = 0x03 +__DFU_STATE_DFU_DOWNLOAD_BUSY = 0x04 +__DFU_STATE_DFU_DOWNLOAD_IDLE = 0x05 +__DFU_STATE_DFU_MANIFEST_SYNC = 0x06 +__DFU_STATE_DFU_MANIFEST = 0x07 +__DFU_STATE_DFU_MANIFEST_WAIT_RESET = 0x08 +__DFU_STATE_DFU_UPLOAD_IDLE = 0x09 +__DFU_STATE_DFU_ERROR = 0x0a + + +# USB device handle +__dev = None + +__verbose = None + +# USB DFU interface +__DFU_INTERFACE = 0 + +def init(): + global __dev + __dev = usb.core.find(idVendor=__VID, idProduct=__PID) + if __dev is None: + raise ValueError('No DFU device found') + + # Claim DFU interface + usb.util.claim_interface(__dev, __DFU_INTERFACE) + + # Clear status + clr_status() + +def clr_status(): + __dev.ctrl_transfer(0x21, __DFU_CLRSTATUS, 0, __DFU_INTERFACE, None, __TIMEOUT) + +def get_status(): + stat =__dev.ctrl_transfer(0xA1, __DFU_GETSTATUS, 0, __DFU_INTERFACE, 6, 20000) + # print (__DFU_STAT[stat[4]], stat) + return stat[4] + +def mass_erase(): + # Send DNLOAD with first byte=0x41 + __dev.ctrl_transfer(0x21, __DFU_DNLOAD, 0, __DFU_INTERFACE, "\x41", __TIMEOUT) + + # Execute last command + if (get_status() != __DFU_STATE_DFU_DOWNLOAD_BUSY): + raise Exception("DFU: erase failed") + + # Check command state + if (get_status() != __DFU_STATE_DFU_DOWNLOAD_IDLE): + raise Exception("DFU: erase failed") + +def page_erase(addr): + if __verbose: + print ("Erasing page: 0x%x..."%(addr)) + + # Send DNLOAD with first byte=0x41 and page address + buf = struct.pack("