| 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 |  |