freemyipod r951 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r950‎ | r951 | r952 >
Date:12:59, 16 June 2014
Author:theseven
Status:new
Tags:
Comment:
libemcore: Use bulk transfers if possible
Modified paths:
  • /emcore/trunk/tools/emcore.py (modified) (history)
  • /emcore/trunk/tools/libemcore.py (modified) (history)

Diff [purge]

Index: emcore/trunk/tools/libemcore.py
@@ -128,6 +128,23 @@
129129 return self.lib.monitorcommand(struct.pack("<IIII%ds" % len(data), 5, addr, len(data), 0, data), "III", (None, None, None))
130130
131131 @command()
 132+ def _readmem_bulk(self, addr, size):
 133+ """ Reads the memory from location 'addr' with size 'size'
 134+ from the device. Can handle unlimited amounts of bytes,
 135+ however the address and size should be cacheline aligned.
 136+ """
 137+ return self.lib.recvbulk(struct.pack("<III", 1, addr, size), size)
 138+
 139+ @command()
 140+ def _writemem_bulk(self, addr, data):
 141+ """ Writes the data in 'data' to the location 'addr'
 142+ in the memory of the device. Can handle unlimited amounts of bytes,
 143+ however the address and size should be cacheline aligned.
 144+
 145+ """
 146+ return self.lib.sendbulk(struct.pack("<III", 1, addr, len(data)), data)
 147+
 148+ @command()
132149 def getversioninfo(self):
133150 """ This returns the emCORE version and device information. """
134151 resp = self.lib.monitorcommand(struct.pack("<IIII", 1, 0, 0, 0), "IBBBBI", ("revision", "majorv", "minorv", "patchv", "swtypeid", "hwtypeid"))
@@ -173,6 +190,19 @@
174191 """
175192 data = b""
176193 self.logger.debug("Downloading %d bytes from 0x%X\n" % (size, addr))
 194+ try:
 195+ if self.lib.bulkin and size > 0x800:
 196+ if addr & 63:
 197+ align = 64 - (addr & 63)
 198+ data += self._readmem(addr, align)
 199+ addr += align
 200+ size -= align
 201+ align = size & 63
 202+ size -= align
 203+ data += self._readmem_bulk(addr, size)
 204+ addr += size
 205+ size = align
 206+ except: self.logger.warn("Bulk read interface failed, falling back to slow reads\n")
177207 while size > 0:
178208 readsize = min(size, 0xf00)
179209 data += self._readmem(addr, readsize)
@@ -188,6 +218,21 @@
189219 size = len(data)
190220 self.logger.debug("Uploading %d bytes to 0x%X\n" % (size, addr))
191221 offset = 0
 222+ try:
 223+ if self.lib.bulkin and size > 0x800:
 224+ if addr & 63:
 225+ align = 64 - (addr & 63)
 226+ self._writemem(addr, data[offset:offset+align])
 227+ offset += align
 228+ addr += align
 229+ size -= align
 230+ align = size & 63
 231+ size -= align
 232+ self._writemem_bulk(addr, data[offset:offset+size])
 233+ offset += size
 234+ addr += size
 235+ size = align
 236+ except: self.logger.warn("Bulk write interface failed, falling back to slow writes\n")
192237 while size > 0:
193238 writesize = min(size, 0xf00)
194239 self._writemem(addr, data[offset:offset+writesize])
@@ -1019,6 +1064,8 @@
10201065 def connect(self):
10211066 self.dev = Dev(self.idVendor, self.idProduct, self.idProductMask, self.logger)
10221067 self.connected = True
 1068+ self.bulkout = True if self.dev.bulkout else False
 1069+ self.bulkin = True if self.dev.bulkin else False
10231070
10241071 def monitorcommand(self, cmd, rcvdatatypes=None, rcvstruct=None):
10251072 self.logger.debug("Sending monitorcommand [0x%s]\n" % base64.b16encode(cmd[3::-1]).decode("ascii"))
@@ -1055,6 +1102,14 @@
10561103 raise DeviceError("Device busy")
10571104 else:
10581105 return writelen
 1106+
 1107+ def sendbulk(self, cmd, data):
 1108+ self.logger.debug("Sending bulk command [0x%s]\n" % base64.b16encode(cmd[3::-1]).decode("ascii"))
 1109+ return self.dev.sendbulk(cmd, data)
 1110+
 1111+ def recvbulk(self, cmd, size):
 1112+ self.logger.debug("Receiving bulk command [0x%s]\n" % base64.b16encode(cmd[3::-1]).decode("ascii"))
 1113+ return self.dev.recvbulk(cmd, size)
10591114
10601115
10611116 class Dev(object):
@@ -1068,6 +1123,8 @@
10691124
10701125 self.dev = None
10711126 self.interface = None
 1127+ self.bulkout = None
 1128+ self.bulkin = None
10721129 self.claimed = False
10731130 self.timeout = 1000
10741131
@@ -1108,6 +1165,14 @@
11091166 self.logger.debug("%02x:%02x:%02x\n" % (intf.bInterfaceClass, intf.bInterfaceSubClass, intf.bInterfaceProtocol))
11101167 if intf.bInterfaceClass == 0xff and intf.bInterfaceSubClass == 0 and intf.bInterfaceProtocol == 0:
11111168 self.interface = intf.bInterfaceNumber
 1169+ for ep in intf:
 1170+ if not ep.bEndpointAddress & 0x80:
 1171+ self.bulkout = ep
 1172+ break
 1173+ for ep in intf:
 1174+ if ep.bEndpointAddress & 0x80:
 1175+ self.bulkin = ep
 1176+ break
11121177 break
11131178 if self.interface is None:
11141179 raise DeviceNotFoundError()
@@ -1123,17 +1188,33 @@
11241189 def send(self, data):
11251190 if len(data) > 0x1000: raise DeviceError("Attempting to send a message that is too big!")
11261191 size = self.dev.ctrl_transfer(0x41, 0x00, 0, self.interface, data, self.timeout)
1127 - if size != len(data):
1128 - raise SendError("Not all data was written!")
1129 - return len
 1192+ if size != len(data): raise SendError("Not all data was written!")
 1193+ return size
11301194
11311195 def receive(self, size):
11321196 if size > 0x1000: raise DeviceError("Attempting to receive a message that is too big!")
1133 - read = self.dev.ctrl_transfer(0xc1, 0x00, 0, self.interface, size, self.timeout)
1134 - if len(read) != size:
1135 - raise ReceiveError("Requested size and read size don't match!")
1136 - return read
 1197+ data = self.dev.ctrl_transfer(0xc1, 0x00, 0, self.interface, size, self.timeout)
 1198+ if len(data) != size: raise ReceiveError("Requested size and read size don't match!")
 1199+ return data
11371200
 1201+ def sendbulk(self, cmd, data):
 1202+ size = self.dev.ctrl_transfer(0x42, 0x00, 0, self.bulkout.bEndpointAddress, cmd, self.timeout)
 1203+ if size != len(cmd):
 1204+ raise SendError("Bulk send command could not be fully sent (%d of %d)!" % (size, len(cmd)))
 1205+ size = self.bulkout.write(data, self.timeout)
 1206+ if size != len(data):
 1207+ raise SendError("Bulk data could not be fully sent (%d of %d)!" % (size, len(data)))
 1208+ return size
 1209+
 1210+ def recvbulk(self, cmd, size):
 1211+ size = self.dev.ctrl_transfer(0x42, 0x00, 0, self.bulkin.bEndpointAddress, cmd, self.timeout)
 1212+ if size != len(cmd):
 1213+ raise ReceiveError("Bulk receive command could not be fully sent (%d of %d)!" % (size, len(cmd)))
 1214+ data = self.bulkin.read(size, self.timeout)
 1215+ if len(data) != size:
 1216+ raise SendError("Bulk data could not be fully received (%d of %d)!" % (len(cmd), size))
 1217+ return data
 1218+
11381219
11391220 if __name__ == "__main__":
11401221 from misc import Logger
Index: emcore/trunk/tools/emcore.py
@@ -141,8 +141,8 @@
142142 self.logger.error(usage("Argument Error in '%s': Wrong argument count" % func, specific=func))
143143 else:
144144 raise
145 - except libemcore.usb.core.USBError:
146 - self.logger.error("There is a problem with the USB connection.\n")
 145+# except libemcore.usb.core.USBError:
 146+# self.logger.error("There is a problem with the USB connection.\n")
147147 else:
148148 usage("No such command!", docstring = False)
149149