Revision: 1358
Author: [email protected]
Date: Mon Sep 28 14:09:16 2009
Log: add USB bootloader host application python scripts
http://code.google.com/p/jallib/source/detail?r=1358
Added:
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/UsbBootLoader.py
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/UsbBootLoaderDriver.py
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/UsbBootLoaderW.py
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/connec9.ico
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/intelhex.py
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/setup.py
=======================================
--- /dev/null
+++
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/UsbBootLoader.py
Mon Sep 28 14:09:16 2009
@@ -0,0 +1,578 @@
+#!/usr/bin/python
+#
+#
+# Title: jallib USB bootloader (auto start) application
+# Author: Albert Faber, Copyright (c) 2009, all rights reserved.
+# Adapted-by:
+# Compiler:
+#
+# This file is part of jallib (http://jallib.googlecode.com)
+# Released under the BSD license
(http://www.opensource.org/licenses/bsd-license.php)
+#
+# Sources:
+#
+# Description: USB loader command line tool, see help for options and usage
+#
+# Dependencies: you'll need to install the LIBUSB package in order to use
the application
+#
+# Notes:
+#
+
+import sys
+import os
+import usb
+import time
+
+from array import array
+
+import intelhex
+from intelhex import IntelHex
+
+import UsbBootLoaderDriver
+from UsbBootLoaderDriver import UsbBootLoaderDriver
+
+
+class UsbBootLoader():
+
+ max_program_flash_size = 128 * 1024
+ erase_frame_size = 64
+ program_flash_frame_size = 16
+ device_entry = None
+ bootloader_offset = 0x800
+ flash_hex = None
+
+ ID_location = 0x200000
+ ID_location_size = 8
+ config_location = 0x300000
+ config_location_size = 14
+
+
+ # table with supported USB devices
+ device_table= \
+ {
+ # device_id,
+ # PIC name,
+ # flash size(in bytes)
+ # eeprom size (in bytes)
+ 0x4740: ['18f13k50' , 0x02000, 0x80 ],
+ 0x4700: ['18lf13k50' , 0x02000, 0x80 ],
+
+ 0x4760: ['18f14k50' , 0x04000, 0xFF ],
+ 0x4720: ['18f14k50' , 0x04000, 0xFF ],
+
+ 0x2420: ['18f2450' , 0x04000, 0x00 ],
+ 0x1260: ['18f2455' , 0x06000, 0xFF ],
+ 0x2A60: ['18f2458' , 0x06000, 0xFF ],
+
+ 0x4C00: ['18f24J50' , 0x04000, 0x00 ],
+ 0x4CC0: ['18lf24J50' , 0x04000, 0x00 ],
+
+ 0x1240: ['18f2550' , 0x08000, 0xFF ],
+ 0x2A40: ['18f2553' , 0x08000, 0xFF ],
+ 0x4C20: ['18f25J50' , 0x08000, 0x00 ],
+ 0x4CE0: ['18lf25J50' , 0x08000, 0x00 ],
+
+ 0x4C40: ['18f26J50' , 0x10000, 0x00 ],
+ 0x4D00: ['18lf26J50' , 0x10000, 0x00 ],
+
+ 0x1200: ['18f4450' , 0x04000, 0x00 ],
+ 0x1220: ['18f4455' , 0x06000, 0x00 ],
+ 0x2A20: ['PIC18F4458', 0x06000, 0xFF ],
+
+ 0x4C60: ['18f44J50' , 0x04000, 0x00 ],
+ 0x4D20: ['18lf44J50' , 0x04000, 0x00 ],
+
+ 0x1200: ['18f4550' , 0x08000, 0xFF ],
+ 0x2A00: ['18f4553' , 0x08000, 0xFF ],
+
+ 0x4C80: ['18f45J50' , 0x08000, 0x00 ],
+ 0x4D40: ['18lf45J50' , 0x08000, 0x00 ],
+
+ 0x4CA0: ['18f46J50' , 0x10000, 0x00 ],
+ 0x4D60: ['18f46J50' , 0x10000, 0x00 ],
+
+ 0x4100: ['18f65J50' , 0x08000, 0x00 ],
+ 0x1560: ['18f66J50' , 0x10000, 0x00 ],
+ 0x4160: ['18f66J55' , 0x18000, 0x00 ],
+ 0x4180: ['18f67J50' , 0x20000, 0x00 ],
+ 0x41A0: ['18f85J50' , 0x08000, 0x00 ],
+ 0x41E0: ['18f86J50' , 0x10000, 0x00 ],
+ 0x1F40: ['18f86J55' , 0x18000, 0x00 ],
+ 0x4220: ['18f87J50' , 0x20000, 0x00 ]
+ }
+
+
+ def __init__(self, ):
+ if sys.platform=="win32":
+ self.fileseparator="\\"
+ else:
+ self.fileseparator="/"
+
+
+ def WaitForDevice(self):
+
+ device_found = False
+ version_number = None
+
+ while version_number == None :
+ usb_driver = UsbBootLoaderDriver()
+
+ try:
+ version_number = usb_driver.ReadVersion()
+
+ except:
+ """ catch exception """
+
+ usb_driver.CloseDevice()
+ return version_number
+
+ def GetDeviceType(self):
+
+ usb_driver = UsbBootLoaderDriver()
+
+ strRet = "PIC not found"
+
+ try:
+ # read device ID from location 0x3FFFFE
+ rx_buffer = usb_driver.ReadFlashBlock( 0x3F, 0xFF,
0xFE, 2 )
+
+ print versionNumber
+ device_found = True
+ except:
+ """ catch exception """
+
+ usb_driver.CloseDevice()
+
+ device_id = ( ( int( rx_buffer[1] ) ) << 8 ) + int(
rx_buffer[0] )
+ deivce_rev = device_id & 0x001F
+
+
+ # mask revision number
+ device_id = device_id & 0xFFE0
+
+ hexValue = "%X" % device_id
+
+ self.program_flash_size = 0x0000
+
+ for device_entry in self.device_table :
+ if ( device_id == device_entry ) :
+ self.program_flash_size = self.device_table[
device_entry ][1]
+ self.device_entry = device_entry
+
+ def GetPICName( self ) :
+ if ( self.device_entry == None ) :
+ self.GetDeviceType()
+ if ( self.device_entry != None ) :
+ return self.device_table[ self.device_entry ][0]
+ return None
+
+ def GetPICDeviceID( self ) :
+ if ( self.device_entry == None ) :
+ self.GetDeviceType()
+ if ( self.device_entry != None ) :
+ return "%04X" % self.device_entry
+ else :
+ return None
+
+
+ def LoadHexFile(self, filename):
+ # start with a clean hex file
+ self.file_hex = intelhex.IntelHex()
+ self.file_hex.readfile( filename )
+
+
+
+ def EraseUserFlash(self):
+
+ usb_driver = UsbBootLoaderDriver()
+
+ try:
+ for address in range( self.bootloader_offset,
self.program_flash_size,
self.erase_frame_size ) :
+
+ addr_u = ( address >> 16 ) & 0xFF
+ addr_h = ( address >> 8 ) & 0xFF
+ addr_l = ( address ) & 0xFF
+
+ usb_driver.EraseFlashBlock( 1, addr_u, addr_h,
addr_l )
+
+ except:
+ print "Erase failed \n"
+
+ usb_driver.CloseDevice()
+
+ def _WriteFlashRegion(self, usb_driver, start_address, end_address,
frame_size ):
+
+ for address in range( start_address, end_address, frame_size ) :
+
+ addr_u = ( address >> 16 ) & 0xFF
+ addr_h = ( address >> 8 ) & 0xFF
+ addr_l = ( address ) & 0xFF
+
+ data = []
+
+ # copy data to flex_hex memory
+ for i in range(0,frame_size):
+ data.append( self.file_hex[ address + i ] )
+
+ data = usb_driver.WriteFlashBlock( addr_u, addr_h,
addr_l, frame_size )
+
+
+
+ def WriteFlash(self, start_address, end_address, write_eeprom,
write_config = False, write_id = False):
+
+ usb_driver = UsbBootLoaderDriver()
+
+ # start with a clean hex file
+ self.flash_hex = intelhex.IntelHex()
+
+ if ( start_address == None ) :
+ start_address = 0
+
+ if ( end_address == None ) :
+ end_address = self.program_flash_size
+
+ if ( end_address > self.program_flash_size ) :
+ end_address = self.program_flash_size
+
+ start_address = start_address & 0xFFFFF0
+
+
+ max_num_frames = self.max_program_flash_size /
self.erase_frame_size
+ num_frames = self.program_flash_size / self.erase_frame_size
+
+ base_address = 0
+
+ usb_driver = UsbBootLoaderDriver()
+
+ self.EraseUserFlash()
+
+ base_address = 0
+
+
+ for i in range(0,num_frames):
+
+ valid_frame = False
+
+ # check if there is any data to flash in the memory
region
+ for j in range(0,self.erase_frame_size):
+ byteVal = self.file_hex[ base_address + j ]
+ if byteVal != 0xFF :
+ valid_frame = True
+
+ # got some valid data, do erase / 4 writes
+ if ( valid_frame ) :
+
+ if ( j < ( self.bootloader_offset /
self.erase_frame_size ) ) :
+ print "Overwriting boot block !!"
+ elif ( j > num_frames ) :
+ print "HEX file out of bounds!!"
+ else :
+
+ addr_u = ( base_address >> 16 )
& 0xFF
+ addr_h = ( base_address >> 8 )
& 0xFF
+ addr_l = ( base_address )
& 0xFF
+
+ # usb_driver.EraseFlashBlock(
1, addr_u, addr_h, addr_l )
+ #print
"self.usb_driver.EraseFlashBlock( 1, " + str( addr_u ) + " "
+ str( addr_h ) + " " + str( addr_l ) + " )"
+
+ block_offset = 0
+
+ for i in range( 0,
self.erase_frame_size /
self.program_flash_frame_size ) :
+ addr_u = ( (
base_address + block_offset ) >> 16 ) & 0xFF
+ addr_h = ( (
base_address + block_offset ) >> 8 ) & 0xFF
+ addr_l = ( (
base_address + block_offset ) ) & 0xFF
+
+ buffer = []
+
+ for j in range( 0,
self.program_flash_frame_size ) :
+ buffer.append(
self.file_hex[ base_address + block_offset + j ] )
+
+
usb_driver.WriteFlashBlock( buffer, addr_u, addr_h, addr_l )
+ #print
"self.usb_driver.WriteFlashBlock( 1, " + str( addr_u ) + " "
+ str( addr_h ) + " " + str( addr_l ) + " )"
+
+ block_offset =
block_offset + self.program_flash_frame_size
+
+
+ base_address = base_address + self.erase_frame_size
+
+ usb_driver.CloseDevice()
+
+
+ def _ReadFlashRegion(self, usb_driver, start_address, end_address,
frame_size ):
+
+ for address in range( start_address, end_address, frame_size ) :
+
+ addr_u = ( address >> 16 ) & 0xFF
+ addr_h = ( address >> 8 ) & 0xFF
+ addr_l = ( address ) & 0xFF
+
+ data = usb_driver.ReadFlashBlock( addr_u, addr_h,
addr_l, frame_size )
+
+ # copy data to flex_hex memory
+ for i in range(0,frame_size):
+ self.flash_hex[ address + i ] = data[i ]
+ # print "READ REGION " + "%02X" %
self.flash_hex[ address + i ]
+
+
+ def ReadFlash(self, start_address, end_address, read_eeprom = False,
read_config = False, read_id = False):
+
+ usb_driver = UsbBootLoaderDriver()
+
+ # start with a clean hex file
+ self.flash_hex = intelhex.IntelHex()
+
+ if ( start_address == None ) :
+ start_address = 0
+
+ if ( end_address == None ) :
+ end_address = self.program_flash_size
+
+ if ( end_address > self.program_flash_size ) :
+ end_address = self.program_flash_size
+
+ start_address = start_address & 0xFFFFF0
+ end_address = end_address & 0xFFFFF0
+
+
+ try:
+ self._ReadFlashRegion( usb_driver, start_address,
end_address,
self.program_flash_frame_size )
+ except:
+ print "Read failed \n"
+
+
+
+ try:
+ if read_id :
+ # print "READ ID FROM " + "%06X" %
self.ID_location + " TO "
+ "%06X" % ( self.ID_location + self.ID_location_size )
+ self._ReadFlashRegion( usb_driver,
self.ID_location, self.ID_location
+ self.ID_location_size, self.ID_location_size )
+ except:
+ print "Read ID location failed \n"
+
+
+
+ try:
+ if read_config :
+ # print "READ CONFIG FROM " + "%06X" %
self.config_location + " TO "
+ "%06X" % ( self.config_location + self.config_location_size )
+ self._ReadFlashRegion( usb_driver,
self.config_location,
self.config_location + self.config_location_size, self.config_location_size
)
+ except:
+ print "Read config failed \n"
+
+ # print "CONFIG AT 0 " + "%02X" % flash_hex[
self.config_location + 2 ]
+
+
+ usb_driver.CloseDevice()
+
+
+ def DumpHexMemory(self, data, start_address, end_address ):
+
+
+ strOut = ""
+
+ try:
+ for address in range( start_address, end_address, 16 ) :
+
+ strTmp = "%06X" % address + " "
+
+ for i in range(0,16):
+ if ( ( address + i ) < end_address ):
+ strTmp = strTmp + "%02X" %
data[ address + i ] + " "
+
+ strOut = strOut + strTmp + "\n"
+ except:
+ print "Dump failed \n"
+ strOut = None
+
+ return strOut
+
+
+ def DumpFlashHexMemory(self, start_address, end_address ):
+ if ( end_address == None ) :
+ end_address = self.program_flash_size
+ return self.DumpHexMemory( self.flash_hex, start_address,
end_address )
+
+ def DumpFlashIDLocation(self):
+ return self.DumpHexMemory( self.flash_hex, self.ID_location,
self.ID_location + self.ID_location_size )
+ def DumpFlashConfig(self):
+ return self.DumpHexMemory( self.flash_hex,
self.config_location,
self.config_location + self.config_location_size )
+
+
+ def DumpFileHexMemory(self, start_address, end_address ):
+ if ( end_address == None ) :
+ end_address = self.program_flash_size
+ return self.DumpHexMemory( self.file_hex, start_address,
end_address )
+
+ def WriteFlashHexToFile(self, fname, start_address ):
+ self.flash_hex.writefile( fname, start_address )
+
+ def ResetDevice(self):
+ try:
+ usb_driver = UsbBootLoaderDriver()
+ usb_driver.Reset()
+ usb_driver.CloseDevice()
+ except:
+ """ catch exception """
+
+
+if __name__ == '__main__':
+ import getopt
+ import os
+ import sys
+
+ usage = '''Python USB Bootloader utility.
+Usage:
+ python UsbBootLoader.py [options] command file.hex
+
+Arguments:
+ file.hex name of hex file to processing.
+ command read ; read data from flash, write to file.hex
if specified
+ dump ; read data from flash, dumps data to
console
+ write; read data from file.hex, write to flash
+ erase; erase user data, NOTE:
+
file.hex/range/eeprom/configuration/id_location options will be ignored
+Options:
+ -h, --help this help message.
+ -c, --configuration read/write configuration bytes
+ -e, --eeprom read/write eeprom bytes
+ -i, --id-location read/write ID locations bytes
+ -r, --range=START:END specify address range for reading/writing
+ (ascii hex value).
+
+ -x, --reset reset on exit
+ -v, --verbose shows details info
+'''
+
+ start = 0x0800
+ end = None
+ configuration = False
+ eeprom = False
+ id_location = False
+ verbose = 0
+ reset = False
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "hceir:vx",
+
["help", "configuration", "eeprom", "id-location", "range=",
+ "verbose","reset"])
+
+ for o, a in opts:
+ if o in ("-h", "--help"):
+ print usage
+ sys.exit(0)
+ elif o in ("-c", "--configuration"):
+ try:
+ configuration = True
+ except:
+ raise getopt.GetoptError, 'Bad
configuration value'
+ elif o in ("-e", "--eeprom"):
+ try:
+ eeprom = True
+ except:
+ raise getopt.GetoptError, 'Bad eeprom
value'
+ elif o in ("-x", "--reset"):
+ try:
+ reset = True
+ except:
+ raise getopt.GetoptError, 'Bad reset
value'
+ elif o in ("-i", "--id-location"):
+ try:
+ id_location = True
+ except:
+ raise getopt.GetoptError, 'Bad
id_location value'
+ elif o in ("-r", "--range"):
+ try:
+ l = a.split(":")
+ if l[0] != '':
+ start = int(l[0], 16)
+ if l[1] != '':
+ end = int(l[1], 16)
+ except:
+ raise getopt.GetoptError, 'Bad range
value(s)'
+ elif o in ("-v", "--verbose"):
+ try:
+ verbose = 1
+ except:
+ raise getopt.GetoptError, 'Bad verbose
value'
+
+ if not args:
+ raise getopt.GetoptError, 'Hex file is not specified'
+
+ if len(args) > 3:
+ raise getopt.GetoptError, 'Too many arguments'
+
+ except getopt.GetoptError, msg:
+ print msg
+ print usage
+ sys.exit(2)
+
+ command = args[0]
+ file_name = None
+
+ if len(args) == 2:
+ file_name = args[1]
+ # import os.path
+ # name, ext = os.path.splitext(fin)
+ # fout = name + ".bin"
+ # else:
+ # fout = args[1]
+
+ print "COMMAND " + command
+ if file_name == None :
+ print "FILENAME NONE"
+ else:
+ print "FILENAME " + file_name
+
+ #sys.exit(hex2bin(fin, fout, start, end, size, pad))
+
+ print"Waiting for USB PIC bootloader device ..."
+
+ test_loader = UsbBootLoader()
+
+ print"Boot device version number " + str( test_loader.WaitForDevice() )
+
+ pic_name = test_loader.GetPICName()
+ device_id = test_loader.GetPICDeviceID()
+
+ if ( pic_name != None ) :
+
+ print "Found PIC: device_id " + device_id + " name " +
test_loader.GetPICName()
+
+ if command == "read":
+ if file_name == None :
+ print "Read command failed, file name not
specified "
+ sys.exit(1)
+
+ test_loader.ReadFlash( start, end , eeprom,
configuration, id_location)
+ test_loader.WriteFlashHexToFile( file_name, start )
+
+ elif command == "write":
+
+
+ if file_name == None :
+ print "Write command failed, file name not
specified "
+ else:
+ if not os.path.isfile(file_name):
+ print "File not found " + file_name
+ sys.exit(1)
+ print "Flashing file " + file_name
+ test_loader.LoadHexFile( file_name )
+ test_loader.WriteFlash( start, end, eeprom,
configuration, id_location)
+
+ elif command == "erase":
+ print "Erase command "
+ test_loader.EraseUserFlash()
+ elif command == "dump":
+ test_loader.ReadFlash( start, end , eeprom,
configuration, id_location)
+ print test_loader.DumpFlashHexMemory( start, end )
+ else :
+ print "UNKNOWN COMMAND " + command
+ print usage
+ sys.exit(0)
+
+ if reset == True :
+ test_loader.ResetDevice()
+
+ else:
+ print "PIC type " + device_id + " not supported"
+
+ sys.exit( 0 )
+
=======================================
--- /dev/null
+++
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/UsbBootLoaderDriver.py
Mon Sep 28 14:09:16 2009
@@ -0,0 +1,203 @@
+#!/usr/bin/python
+#
+#
+# Title: jallib USB bootloader driver
+# Author: Albert Faber, Copyright (c) 2009, all rights reserved.
+# Adapted-by:
+# Compiler:
+#
+# This file is part of jallib (http://jallib.googlecode.com)
+# Released under the BSD license
(http://www.opensource.org/licenses/bsd-license.php)
+#
+# Sources:
+#
+# Description: low level USB driver function
+#
+# Dependencies: you'll need to install the LIBUSB package in order to use
the driver
+#
+# Notes:
+#
+
+import sys
+import os
+import usb
+import time
+from array import array
+
+import intelhex
+from intelhex import IntelHex
+
+
+class DeviceDescriptor:
+ def __init__(self, vendor_id, product_id, interface_id) :
+ self.vendor_id = vendor_id
+ self.product_id = product_id
+ self.interface_id = interface_id
+
+ def get_device(self) :
+ buses = usb.busses()
+ for bus in buses :
+ for device in bus.devices :
+ if device.idVendor == self.vendor_id :
+ if device.idProduct ==
self.product_id :
+ return device
+ return None
+
+
+class UsbBootLoaderDriverError( IOError ):
+ "errors raised by UsbBootLoaderDriver, derived from IOError"
+ pass
+
+
+class UsbBootLoaderDriver():
+
+ # USB related constants
+ TIMEOUT_XMIT = 1200
+ TIMEOUT_RECV = 1200
+
+ VENDOR_ID = 0x04D8 #: Vendor Id
+ PRODUCT_ID = 0x000b #: Product Id for the bridged usb cable
+ INTERFACE_ID = 0 #: The interface we use to talk to the device
+ BULK_IN_EP = 0x81 #: Endpoint for Bulk reads
+ BULK_OUT_EP = 0x01 #: Endpoint for Bulk writes
+ PACKET_LENGTH = 0x40 #: 64 bytes
+
+ # Bootloader commands
+ CMD_READ_VERSION = 0x00
+ CMD_READ_FLASH = 0x01
+ CMD_WRITE_FLASH = 0x02
+ CMD_ERASE_FLASH = 0x03
+ CMD_READ_EEDATA = 0x04
+ CMD_WRITE_EEDATA = 0x05
+ CMD_READ_CONFIG = 0x06
+ CMD_WRITE_CONFIG = 0x07
+ CMD_UPDATE_LED = 0x32
+ CMD_RESET = 0xFF
+
+ tx_buffer = []
+ rx_buffer = []
+
+ Error_Prefix = ''
+
+ # make device descriptor
+ device_descriptor = DeviceDescriptor(VENDOR_ID, PRODUCT_ID,
INTERFACE_ID )
+
+
+ def Raise( self, Message ):
+ """raise a UsbBootLoaderDriver with suitable prefix"""
+ # print "RAISE EXCEPTION"
+ #raise UsbBootLoaderDriverError, self.Error_Prefix + Message
+ raise Message
+
+
+ def __init__(self,) :
+ # The actual device (PyUSB object)
+ self.device = self.device_descriptor.get_device()
+
+ # Handle that is used to communicate with device. Setup in
L{open}
+ self.handle = None
+
+
+ def _open_device( self ) :
+ """ Open device interface """
+
+ if ( self.handle != None ) :
+ _close_device()
+
+ self.device = self.device_descriptor.get_device()
+
+ if self.device:
+ try:
+ self.handle = self.device.open()
+ self.handle.setConfiguration( 1 )
+
self.handle.claimInterface(self.device_descriptor.interface_id)
+ except Exception, err:
+ self.Raise( err )
+
+ def _close_device( self ):
+ """ Release device interface """
+ if ( self.handle != None ) :
+ try:
+ #self.handle.reset()
+ self.handle.releaseInterface()
+ except Exception, err:
+ self.Raise( err )
+ self.handle, self.device = None, None
+
+
+ def _ExchangeMessage( self, rx_bytes ) :
+ """ exchange message with firmware """
+
+ if ( self.handle == None ) :
+ self._open_device()
+ if ( self.handle == None ) :
+ self.Raise( "USB device not found" )
+
+ tx_bytes = self.handle.bulkWrite(self.BULK_OUT_EP,
self.tx_buffer,
self.TIMEOUT_XMIT)
+
+ if ( tx_bytes != len( self.tx_buffer) ) :
+ self.Raise( "ExchangeMessage bulkWrite failed" )
+ else:
+ if rx_bytes > 0 :
+ self.rx_buffer =
self.handle.bulkRead(self.BULK_IN_EP, rx_bytes,
self.TIMEOUT_RECV)
+
+ if ( len( self.rx_buffer ) != rx_bytes ) :
+ self.Raise( "ExchangeMessage bulkRead
failed" )
+
+ def OpenDevice( self ) :
+ self._open_device()
+
+ def CloseDevice( self ) :
+ self._close_device()
+
+ def EraseFlashBlock( self, num_blocks, addr_u, addr_h, addr_l ) :
+ """ erase flash N blocks of 64 bytes"""
+
+ # log the address
+ # print"Erase flash " + "%02X" % addr_u + "%02X" % addr_h +
"%02X" %
addr_l
+
+ self.tx_buffer = chr( self.CMD_ERASE_FLASH ) + chr(num_blocks)
+
chr(addr_l) + chr(addr_h) + chr(addr_u)
+ self._ExchangeMessage( 1 )
+
+ def WriteFlashBlock( self, buffer, addr_u, addr_h, addr_l ) :
+ """ write flash block if 16 bytes to the firmware """
+
+ # log the address
+ # print"Write to flash " + "%02X" % addr_u + "%02X" % addr_h +
"%02X" %
addr_l
+
+ assert len( buffer ) == 16
+
+ self.tx_buffer = chr( self.CMD_WRITE_FLASH ) + chr(len( buffer
)) +
chr(addr_l) + chr(addr_h) + chr(addr_u)
+
+ for i in range( 0, 16 ) :
+ self.tx_buffer = self.tx_buffer + chr( buffer[ i ] )
+
+ self._ExchangeMessage( 1 )
+
+
+ def ReadFlashBlock( self, addr_u, addr_h, addr_l, num_read_bytes ) :
+ """ read flash block from firmware """
+ self.tx_buffer = chr( self.CMD_READ_FLASH ) +
chr(num_read_bytes) +
chr(addr_l) + chr(addr_h) + chr(addr_u)
+ self._ExchangeMessage( len( self.tx_buffer) + num_read_bytes )
+
+ # remove command response from received data buffer
+ self.rx_buffer = self.rx_buffer[ len( self.tx_buffer): ]
+
+ return self.rx_buffer
+
+
+ def ReadVersion( self ) :
+ self.tx_buffer = chr( self.CMD_READ_VERSION ) + chr(0) + chr(0)
+ chr(0)
+ chr(0)
+
+ self._ExchangeMessage( 4 )
+
+ return str( int( self.rx_buffer[3])) + "." + str(
int(self.rx_buffer[2]))
+
+ def Reset( self ) :
+ self.tx_buffer = chr( self.CMD_RESET )
+
+ self._ExchangeMessage( 0 )
+
+ return str( int( self.rx_buffer[3])) + "." + str(
int(self.rx_buffer[2]))
+
+
=======================================
--- /dev/null
+++
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/UsbBootLoaderW.py
Mon Sep 28 14:09:16 2009
@@ -0,0 +1,176 @@
+#!/usr/bin/python
+#
+#
+# Title: jallib USB bootloader (auto start) GUI application
+# Author: Albert Faber, Copyright (c) 2009, all rights reserved.
+# Adapted-by:
+# Compiler:
+#
+# This file is part of jallib (http://jallib.googlecode.com)
+# Released under the BSD license
(http://www.opensource.org/licenses/bsd-license.php)
+#
+# Sources:
+#
+# Description: USB loader command line tool, see help for options and usage
+#
+# Dependencies: you'll need to install the LIBUSB and WxWidget (2.8)
package in order to use the application
+#
+# Notes: based on Vascoboot, needs more work
+#
+
+import wx
+import sys
+import os
+import usb
+import time
+
+from array import array
+
+import intelhex
+from intelhex import IntelHex
+
+import UsbBootLoader
+from UsbBootLoader import UsbBootLoader
+
+SetGUI=0
+
+
+
+class UsbBootLoaderGUI(wx.Frame):
+ filename=""
+
+ usb_bootloader = UsbBootLoader()
+
+ def __init__(self, *args, **kwds):
+ if sys.platform=="win32":
+ self.fileseparator="\\"
+ else:
+ self.fileseparator="/"
+ if SetGUI==1:
+ kwds["style"] =
wx.CAPTION|wx.CLOSE_BOX|wx.SYSTEM_MENU
+ wx.Frame.__init__(self, *args, **kwds)
+ self.frame_1_statusbar =
self.CreateStatusBar(1, 0)
+ self.filefield = wx.TextCtrl(self, -1, "")
+ self.loadbutton = wx.Button(self, -1,
"LoadFile...")
+ self.log = wx.TextCtrl(self, -1, "",
style=wx.TE_MULTILINE)
+ self.WriteButton = wx.Button(self, -1, "Write")
+ self.quitbutton = wx.Button(self, -1, "Quit")
+ self.radio_btn_1 = wx.RadioButton(self, -1,
"Microchip",
style=wx.RB_GROUP)
+ self.radio_btn_2 = wx.RadioButton(self, -1,
"Vasco")
+ self.radio_btn_3 = wx.RadioButton(self, -1,
"Custom")
+ self.label_1 = wx.StaticText(self, -1, "Vendor
ID")
+ self.vid = wx.TextCtrl(self, -1, "")
+ self.label_2 = wx.StaticText(self, -1, "Product
ID")
+ self.pid = wx.TextCtrl(self, -1, "")
+
+ self.__set_properties()
+ self.__do_layout()
+
+ self.Bind(wx.EVT_BUTTON, self.Load,
self.loadbutton)
+ self.Bind(wx.EVT_BUTTON, self.Write,
self.WriteButton)
+ self.Bind(wx.EVT_BUTTON, self.Quit,
self.quitbutton)
+ self.Bind(wx.EVT_RADIOBUTTON,
self.SetMicrochip, self.radio_btn_1)
+ self.Bind(wx.EVT_RADIOBUTTON, self.SetVasco,
self.radio_btn_2)
+ self.Bind(wx.EVT_RADIOBUTTON, self.SetCustom,
self.radio_btn_3)
+ self.vid.AppendText("04D8")
+ self.pid.AppendText("000B")
+
+ def __set_properties(self):
+ self.SetTitle("JALLIB USB Bootloader")
+ _icon = wx.EmptyIcon()
+ # this line is used for py2exe compilation
+ #_icon.CopyFromBitmap(wx.Bitmap("connec9.ico",
wx.BITMAP_TYPE_ANY))
+
_icon.CopyFromBitmap(wx.Bitmap(sys.path[0]+self.fileseparator+"connec9.ico",
wx.BITMAP_TYPE_ANY))
+ self.SetIcon(_icon)
+ self.SetSize((428, 450))
+ self.SetBackgroundColour(wx.Colour(216, 216, 191))
+ self.frame_1_statusbar.SetStatusWidths([-1])
+ frame_1_statusbar_fields = ["USB Bootloader version 1.0"]
+ for i in range(len(frame_1_statusbar_fields)):
+
self.frame_1_statusbar.SetStatusText(frame_1_statusbar_fields[i], i)
+ self.filefield.SetMinSize((250, 21))
+ self.log.SetMinSize((340,180))
+
+ def __do_layout(self):
+ sizer_1 = wx.BoxSizer(wx.VERTICAL)
+ sizer_2 = wx.BoxSizer(wx.VERTICAL)
+ sizer_5 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_7 = wx.BoxSizer(wx.VERTICAL)
+ sizer_9 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_8 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_6 = wx.BoxSizer(wx.VERTICAL)
+ sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_3.Add(self.filefield, 0,
wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 15)
+ sizer_3.Add(self.loadbutton, 0, wx.LEFT|wx.RIGHT|
wx.ALIGN_CENTER_VERTICAL, 40)
+ sizer_2.Add(sizer_3, 1, wx.EXPAND, 0)
+ sizer_2.Add(self.log, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 14)
+ sizer_4.Add(self.WriteButton, 0, wx.LEFT|wx.RIGHT|
wx.ALIGN_CENTER_VERTICAL, 69)
+ sizer_4.Add(self.quitbutton, 0, wx.LEFT|wx.RIGHT|
wx.ALIGN_CENTER_VERTICAL, 50)
+ sizer_2.Add(sizer_4, 1, wx.EXPAND, 0)
+ sizer_6.Add(self.radio_btn_1, 0,
wx.LEFT|wx.ALIGN_CENTER_HORIZONTAL,
20)
+ sizer_6.Add(self.radio_btn_2, 0, wx.LEFT|wx.TOP|wx.BOTTOM|
wx.ALIGN_CENTER_HORIZONTAL, 5)
+ sizer_6.Add(self.radio_btn_3, 0,
wx.LEFT|wx.ALIGN_CENTER_HORIZONTAL,
13)
+ sizer_5.Add(sizer_6, 1, wx.EXPAND, 0)
+ sizer_8.Add(self.label_1, 0,
wx.LEFT|wx.ALIGN_CENTER_HORIZONTAL|
wx.ALIGN_CENTER_VERTICAL, 1)
+ sizer_8.Add(self.vid, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 5)
+ sizer_7.Add(sizer_8, 1, wx.EXPAND, 0)
+ sizer_9.Add(self.label_2, 0, wx.ALIGN_CENTER_HORIZONTAL|
wx.ALIGN_CENTER_VERTICAL, 7)
+ sizer_9.Add(self.pid, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 4)
+ sizer_7.Add(sizer_9, 1, wx.EXPAND, 0)
+ sizer_5.Add(sizer_7, 1, wx.EXPAND, 0)
+ sizer_2.Add(sizer_5, 1, wx.EXPAND, 0)
+ sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
+ self.SetSizer(sizer_1)
+ self.Layout()
+ self.Centre()
+
+ def Load(self, event):
+
+ opendlg = wx.FileDialog(
+ self, message="Choose a file",
+ defaultDir=os.getcwd(),
+ defaultFile="",
+ wildcard="Hex file (*.hex)|*.hex",
+ style=wx.OPEN | wx.CHANGE_DIR
+ )
+ if opendlg.ShowModal() == wx.ID_OK:
+ paths = opendlg.GetPaths()
+ for path in paths:
+
self.log.AppendText(os.path.basename(path)+' opened\n')
+ self.filefield.Clear()
+ self.filefield.AppendText(path)
+ self.filename=path
+ self.usb_bootloader.LoadHexFile( self.filename )
+
+ def Write(self, event):
+ pic_name = self.usb_bootloader.GetPICName()
+ device_id = self.usb_bootloader.GetPICDeviceID()
+
+ if ( pic_name != None ) :
+ self.usb_bootloader.WriteFlash(0x800, 0x3FFF, False,
False, False)
+
+
+ def Quit(self, event):
+ sys.exit()
+
+ def SetMicrochip(self, event):
+ print "remove"
+
+ def SetVasco(self, event):
+ print "remove"
+
+ def SetCustom(self, event):
+ print "remove"
+
+
+
+if __name__ == "__main__":
+
+ SetGUI=1
+ app = wx.PySimpleApp(0)
+ wx.InitAllImageHandlers()
+ frame_1 = UsbBootLoaderGUI(None, -1, "")
+ app.SetTopWindow(frame_1)
+ frame_1.Show()
+ app.MainLoop()
=======================================
--- /dev/null
+++
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/connec9.ico
Mon Sep 28 14:09:16 2009
Binary file, no diff available.
=======================================
--- /dev/null
+++
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/intelhex.py
Mon Sep 28 14:09:16 2009
@@ -0,0 +1,413 @@
+#!/usr/bin/python
+#
+#
+# Title: intel hex reader
+# Author: Albert Faber,Alexander Belchenko Copyright (c) 2005-2007 all
rights reserved.
+# Adapted-by:
+# Compiler:
+#
+# This file is part of jallib (http://jallib.googlecode.com)
+# Released under the BSD license
(http://www.opensource.org/licenses/bsd-license.php)
+#
+# Sources:
+#
+# Description: Intel hex file reader
+#
+# Dependencies: -
+#
+# Notes:
+#
+
+from array import array
+from binascii import hexlify, unhexlify
+
+class IntelHex:
+ ''' Intel HEX file reader. '''
+
+ def __init__(self):
+ ''' Constructor.
+ @param fname file name of HEX file or file object.
+ '''
+ #public members
+ self.Error = None
+ self.AddrOverlap = None
+ self.padding = 0x0FF
+ # Start Address
+ self.start_addr = None
+
+ # private members
+ self._buf = {}
+ self._readed = False
+ self._eof = False
+ self._offset = 0
+
+ def readfile(self, fname):
+ ''' Read file into internal buffer.
+ @return True if successful.
+ '''
+ if self._readed:
+ return True
+
+ if not hasattr(fname, "read"):
+ f = file(fname, "rU")
+ fclose = f.close
+ else:
+ f = self._fname
+ fclose = None
+
+ self._offset = 0
+ self._eof = False
+
+ result = True
+
+ for s in f:
+ if not self.decode_record(s):
+ result = False
+ break
+
+ if self._eof:
+ break
+
+ if fclose:
+ fclose()
+
+ self._readed = result
+ return result
+
+ def decode_record(self, s):
+ ''' Decode one record of HEX file.
+ @param s line with HEX record.
+ @return True if line decode OK, or this is not HEX line.
+ False if this is invalid HEX line or checksum error.
+ '''
+ s = s.rstrip('\r\n')
+ if not s:
+ return True # empty line
+
+ if s[0] == ':':
+ try:
+ bin = array('B', unhexlify(s[1:]))
+ except TypeError:
+ # this might be raised by unhexlify when odd hexascii
digits
+ self.Error = "Odd hexascii digits"
+ return False
+ length = len(bin)
+ if length < 5:
+ self.Error = "Too short line"
+ return False
+ else:
+ return True # first char must be ':'
+
+ record_length = bin[0]
+
+ if length != (5 + record_length):
+ self.Error = "Invalid line length"
+ return False
+
+ addr = bin[1]*256 + bin[2]
+
+ record_type = bin[3]
+ if not (0 <= record_type <= 5):
+ self.Error = "Invalid type of record: %d" % record_type
+ return False
+
+ crc = sum(bin)
+ crc &= 0x0FF
+ if crc != 0:
+ self.Error = "Invalid crc"
+ return False
+
+ if record_type == 0:
+ # data record
+ addr += self._offset
+ for i in xrange(4, 4+record_length):
+ if not self._buf.get(addr, None) is None:
+ self.AddrOverlap = addr
+ self._buf[addr] = bin[i]
+ addr += 1 # FIXME: addr should be wrapped on 64K
boundary
+
+ elif record_type == 1:
+ # end of file record
+ if record_length != 0:
+ self.Error = "Bad End-of-File Record"
+ return False
+ self._eof = True
+
+ elif record_type == 2:
+ # Extended 8086 Segment Record
+ if record_length != 2 or addr != 0:
+ self.Error = "Bad Extended 8086 Segment Record"
+ return False
+ self._offset = (bin[4]*256 + bin[5]) * 16
+
+ elif record_type == 4:
+ # Extended Linear Address Record
+ if record_length != 2 or addr != 0:
+ self.Error = "Bad Extended Linear Address Record"
+ return False
+ self._offset = (bin[4]*256 + bin[5]) * 65536
+
+ elif record_type == 3:
+ # Start Segment Address Record
+ if record_length != 4 or addr != 0:
+ self.Error = "Bad Start Segment Address Record"
+ return False
+ if self.start_addr:
+ self.Error = "Start Address Record appears twice"
+ return False
+ self.start_addr = {'CS': bin[4]*256 + bin[5],
+ 'IP': bin[6]*256 + bin[7],
+ }
+
+ elif record_type == 5:
+ # Start Linear Address Record
+ if record_length != 4 or addr != 0:
+ self.Error = "Bad Start Linear Address Record"
+ return False
+ if self.start_addr:
+ self.Error = "Start Address Record appears twice"
+ return False
+ self.start_addr = {'EIP': (bin[4]*16777216 +
+ bin[5]*65536 +
+ bin[6]*256 +
+ bin[7]),
+ }
+
+ return True
+
+ def _get_start_end(self, start=None, end=None):
+ """Return default values for start and end if they are None
+ """
+ if start is None:
+ start = min(self._buf.keys())
+ if end is None:
+ end = max(self._buf.keys())
+ if start > end:
+ start, end = end, start
+ return start, end
+
+ def tobinarray(self, start=None, end=None, pad=None):
+ ''' Convert to binary form.
+ @param start start address of output bytes.
+ @param end end address of output bytes.
+ @param pad fill empty spaces with this value
+ (if None used self.padding).
+ @return array of unsigned char data.
+ '''
+ if pad is None:
+ pad = self.padding
+
+ bin = array('B')
+
+ if self._buf == {}:
+ return bin
+
+ start, end = self._get_start_end(start, end)
+
+ for i in xrange(start, end+1):
+ bin.append(self._buf.get(i, pad))
+
+ return bin
+
+ def tobinstr(self, start=None, end=None, pad=0xFF):
+ ''' Convert to binary form.
+ @param start start address of output bytes.
+ @param end end address of output bytes.
+ @param pad fill empty spaces with this value
+ (if None used self.padding).
+ @return string of binary data.
+ '''
+ return self.tobinarray(start, end, pad).tostring()
+
+ def tobinfile(self, fobj, start=None, end=None, pad=0xFF):
+ '''Convert to binary and write to file.
+
+ @param fobj file name or file object for writing output bytes.
+ @param start start address of output bytes.
+ @param end end address of output bytes.
+ @param pad fill empty spaces with this value
+ (if None used self.padding).
+ '''
+ if not hasattr(fobj, "write"):
+ fobj = file(fobj, "wb")
+ fclose = fobj.close
+ else:
+ fclose = None
+
+ fobj.write(self.tobinstr(start, end, pad))
+
+ if fclose:
+ fclose()
+
+ def minaddr(self):
+ ''' Get minimal address of HEX content. '''
+ aa = self._buf.keys()
+ if aa == []:
+ return 0
+ else:
+ return min(aa)
+
+ def maxaddr(self):
+ ''' Get maximal address of HEX content. '''
+ aa = self._buf.keys()
+ if aa == []:
+ return 0
+ else:
+ return max(aa)
+
+ def __getitem__(self, addr):
+ ''' Get byte from address.
+ @param addr address of byte.
+ @return byte if address exists in HEX file, or self.padding
+ if no data found.
+ '''
+ return self._buf.get(addr, self.padding)
+
+ def __setitem__(self, addr, byte):
+ self._buf[addr] = byte
+
+ def writefile(self, f, write_start_addr=True):
+ """Write data to file f in HEX format.
+
+ @param f filename or file-like object for
writing
+ @param write_start_addr enable or disable writing start address
+ record to file (enabled by default).
+ If there is no start address nothing
+ will be written.
+
+ @return True if successful.
+ """
+ fwrite = getattr(f, "write", None)
+ if fwrite:
+ fobj = f
+ fclose = None
+ else:
+ fobj = file(f, 'w')
+ fwrite = fobj.write
+ fclose = fobj.close
+
+ # start address record if any
+ if self.start_addr and write_start_addr:
+ keys = self.start_addr.keys()
+ keys.sort()
+ bin = array('B', '\0'*9)
+ if keys == ['CS','IP']:
+ # Start Segment Address Record
+ bin[0] = 4 # reclen
+ bin[1] = 0 # offset msb
+ bin[2] = 0 # offset lsb
+ bin[3] = 3 # rectyp
+ cs = self.start_addr['CS']
+ bin[4] = (cs >> 8) & 0x0FF
+ bin[5] = cs & 0x0FF
+ ip = self.start_addr['IP']
+ bin[6] = (ip >> 8) & 0x0FF
+ bin[7] = ip & 0x0FF
+ bin[8] = (-sum(bin)) & 0x0FF # chksum
+ fwrite(':')
+ fwrite(hexlify(bin.tostring()).upper())
+ fwrite('\n')
+ elif keys == ['EIP']:
+ # Start Linear Address Record
+ bin[0] = 4 # reclen
+ bin[1] = 0 # offset msb
+ bin[2] = 0 # offset lsb
+ bin[3] = 5 # rectyp
+ eip = self.start_addr['EIP']
+ bin[4] = (eip >> 24) & 0x0FF
+ bin[5] = (eip >> 16) & 0x0FF
+ bin[6] = (eip >> 8) & 0x0FF
+ bin[7] = eip & 0x0FF
+ bin[8] = (-sum(bin)) & 0x0FF # chksum
+ fwrite(':')
+ fwrite(hexlify(bin.tostring()).upper())
+ fwrite('\n')
+ else:
+ self.Error = ('Invalid start address value: %r'
+ % self.start_addr)
+ return False
+
+ # data
+ minaddr = IntelHex.minaddr(self)
+ maxaddr = IntelHex.maxaddr(self)
+ if maxaddr > 65535:
+ offset = (minaddr/65536)*65536
+ else:
+ offset = None
+
+ while True:
+ if offset != None:
+ # emit 32-bit offset record
+ high_ofs = offset / 65536
+ offset_record = ":02000004%04X" % high_ofs
+ bytes = divmod(high_ofs, 256)
+ csum = 2 + 4 + bytes[0] + bytes[1]
+ csum = (-csum) & 0x0FF
+ offset_record += "%02X\n" % csum
+
+ ofs = offset
+ if (ofs + 65536) > maxaddr:
+ rng = xrange(maxaddr - ofs + 1)
+ else:
+ rng = xrange(65536)
+ else:
+ ofs = 0
+ offset_record = ''
+ rng = xrange(maxaddr + 1)
+
+ csum = 0
+ k = 0
+ record = ""
+ for addr in rng:
+ byte = self._buf.get(ofs+addr, None)
+ if byte != None:
+ if k == 0:
+ # optionally offset record
+ fobj.write(offset_record)
+ offset_record = ''
+ # start data record
+ record += "%04X00" % addr
+ bytes = divmod(addr, 256)
+ csum = bytes[0] + bytes[1]
+
+ k += 1
+ # continue data in record
+ record += "%02X" % byte
+ csum += byte
+
+ # check for length of record
+ if k < 16:
+ continue
+
+ if k != 0:
+ # close record
+ csum += k
+ csum = (-csum) & 0x0FF
+ record += "%02X" % csum
+ fobj.write(":%02X%s\n" % (k, record))
+ # cleanup
+ csum = 0
+ k = 0
+ record = ""
+ else:
+ if k != 0:
+ # close record
+ csum += k
+ csum = (-csum) & 0x0FF
+ record += "%02X" % csum
+ fobj.write(":%02X%s\n" % (k, record))
+
+ # advance offset
+ if offset is None:
+ break
+
+ offset += 65536
+ if offset > maxaddr:
+ break
+
+ # end-of-file record
+ fobj.write(":00000001FF\n")
+ if fclose:
+ fclose()
+
+ return True
=======================================
--- /dev/null
+++
/trunk/project/pic18f14k50_usb_io/bootloader/host_bootloader_application/setup.py
Mon Sep 28 14:09:16 2009
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+#
+#
+# Title: jallib USB bootloader (auto start) setup script
+# Author: Albert Faber, Copyright (c) 2009, all rights reserved.
+# Adapted-by:
+# Compiler:
+#
+# This file is part of jallib (http://jallib.googlecode.com)
+# Released under the BSD license
(http://www.opensource.org/licenses/bsd-license.php)
+#
+# Sources:
+#
+# Description: setup script for bootloader
+#
+# Dependencies: you'll need to install the LIBUSB and wxWidgets(2.8)
package in order to use the application
+#
+# Notes:
+#
+
+from distutils.core import setup
+import py2exe
+
+setup(
+ # The first three parameters are not required, if at least a
+ # 'version' is given, then a versioninfo resource is built from
+ # them and added to the executables.
+ version = "0.5.0",
+ description = "py2exe sample script",
+ name = "py2exe samples",
+
+ # targets to build
+ #windows = ["UsbBootLoaderW.py"],
+ console = ["UsbBootLoader.py"],
+ )
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"jallib" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/jallib?hl=en
-~----------~----~----~----~------~----~------~--~---