Index: emcore/trunk/tools/libemcore.py |
— | — | @@ -128,6 +128,23 @@ |
129 | 129 | return self.lib.monitorcommand(struct.pack("<IIII%ds" % len(data), 5, addr, len(data), 0, data), "III", (None, None, None))
|
130 | 130 |
|
131 | 131 | @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()
|
132 | 149 | def getversioninfo(self):
|
133 | 150 | """ This returns the emCORE version and device information. """
|
134 | 151 | resp = self.lib.monitorcommand(struct.pack("<IIII", 1, 0, 0, 0), "IBBBBI", ("revision", "majorv", "minorv", "patchv", "swtypeid", "hwtypeid"))
|
— | — | @@ -173,6 +190,19 @@ |
174 | 191 | """
|
175 | 192 | data = b""
|
176 | 193 | 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")
|
177 | 207 | while size > 0:
|
178 | 208 | readsize = min(size, 0xf00)
|
179 | 209 | data += self._readmem(addr, readsize)
|
— | — | @@ -188,6 +218,21 @@ |
189 | 219 | size = len(data)
|
190 | 220 | self.logger.debug("Uploading %d bytes to 0x%X\n" % (size, addr))
|
191 | 221 | 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")
|
192 | 237 | while size > 0:
|
193 | 238 | writesize = min(size, 0xf00)
|
194 | 239 | self._writemem(addr, data[offset:offset+writesize])
|
— | — | @@ -1019,6 +1064,8 @@ |
1020 | 1065 | def connect(self):
|
1021 | 1066 | self.dev = Dev(self.idVendor, self.idProduct, self.idProductMask, self.logger)
|
1022 | 1067 | self.connected = True
|
| 1068 | + self.bulkout = True if self.dev.bulkout else False
|
| 1069 | + self.bulkin = True if self.dev.bulkin else False
|
1023 | 1070 |
|
1024 | 1071 | def monitorcommand(self, cmd, rcvdatatypes=None, rcvstruct=None):
|
1025 | 1072 | self.logger.debug("Sending monitorcommand [0x%s]\n" % base64.b16encode(cmd[3::-1]).decode("ascii"))
|
— | — | @@ -1055,6 +1102,14 @@ |
1056 | 1103 | raise DeviceError("Device busy")
|
1057 | 1104 | else:
|
1058 | 1105 | 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)
|
1059 | 1114 |
|
1060 | 1115 |
|
1061 | 1116 | class Dev(object):
|
— | — | @@ -1068,6 +1123,8 @@ |
1069 | 1124 |
|
1070 | 1125 | self.dev = None
|
1071 | 1126 | self.interface = None
|
| 1127 | + self.bulkout = None
|
| 1128 | + self.bulkin = None
|
1072 | 1129 | self.claimed = False
|
1073 | 1130 | self.timeout = 1000
|
1074 | 1131 |
|
— | — | @@ -1108,6 +1165,14 @@ |
1109 | 1166 | self.logger.debug("%02x:%02x:%02x\n" % (intf.bInterfaceClass, intf.bInterfaceSubClass, intf.bInterfaceProtocol))
|
1110 | 1167 | if intf.bInterfaceClass == 0xff and intf.bInterfaceSubClass == 0 and intf.bInterfaceProtocol == 0:
|
1111 | 1168 | 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
|
1112 | 1177 | break
|
1113 | 1178 | if self.interface is None:
|
1114 | 1179 | raise DeviceNotFoundError()
|
— | — | @@ -1123,17 +1188,33 @@ |
1124 | 1189 | def send(self, data):
|
1125 | 1190 | if len(data) > 0x1000: raise DeviceError("Attempting to send a message that is too big!")
|
1126 | 1191 | 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
|
1130 | 1194 |
|
1131 | 1195 | def receive(self, size):
|
1132 | 1196 | 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
|
1137 | 1200 |
|
| 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 | +
|
1138 | 1219 |
|
1139 | 1220 | if __name__ == "__main__":
|
1140 | 1221 | from misc import Logger
|
Index: emcore/trunk/tools/emcore.py |
— | — | @@ -141,8 +141,8 @@ |
142 | 142 | self.logger.error(usage("Argument Error in '%s': Wrong argument count" % func, specific=func))
|
143 | 143 | else:
|
144 | 144 | 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")
|
147 | 147 | else:
|
148 | 148 | usage("No such command!", docstring = False)
|
149 | 149 |
|