| Index: embios/trunk/tools/embios.py | 
| — | — | @@ -1,25 +1,27 @@ | 
|   | 2 | +#!/usr/bin/env python
 | 
| 2 | 3 |  #
 | 
| 3 | 4 |  #
 | 
| 4 |   | -#    Copyright 2010 benedikt93, partially derived from TheSeven's ipod tools
 | 
|   | 5 | +#    Copyright 2010 TheSeven, benedikt93
 | 
| 5 | 6 |  #
 | 
| 6 | 7 |  #
 | 
| 7 |   | -#    This file is part of the freemyipod.org iPod tools.
 | 
|   | 8 | +#    This file is part of emBIOS.
 | 
| 8 | 9 |  #
 | 
| 9 |   | -#    FreeMyIPods' emBIOS and related tools are free software: you can redistribute it and/or
 | 
|   | 10 | +#    emBIOS is free software: you can redistribute it and/or
 | 
| 10 | 11 |  #    modify it under the terms of the GNU General Public License as
 | 
| 11 | 12 |  #    published by the Free Software Foundation, either version 2 of the
 | 
| 12 | 13 |  #    License, or (at your option) any later version.
 | 
| 13 | 14 |  #
 | 
| 14 |   | -#    FreeMyIPods' emBIOS and related tools are distributed in the hope that they will be useful,
 | 
|   | 15 | +#    emBIOS is distributed in the hope that it will be useful,
 | 
| 15 | 16 |  #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
| 16 | 17 |  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
| 17 | 18 |  #    See the GNU General Public License for more details.
 | 
| 18 | 19 |  #
 | 
| 19 |   | -#    You should have received a copy of the GNU General Public License along
 | 
| 20 |   | -#    with FreeMyIPods' emBIOS and related tools.  If not, see <http://www.gnu.org/licenses/>.
 | 
|   | 20 | +#    You should have received a copy of the GNU General Public License
 | 
|   | 21 | +#    along with emBIOS.  If not, see <http://www.gnu.org/licenses/>.
 | 
| 21 | 22 |  #
 | 
| 22 | 23 |  #
 | 
| 23 | 24 |  
 | 
|   | 25 | +# note: handles commands 1 to 20
 | 
| 24 | 26 |  
 | 
| 25 | 27 |  import sys
 | 
| 26 | 28 |  import time
 | 
| — | — | @@ -46,6 +48,38 @@ | 
| 47 | 49 |    print "    If <force> is 1, the poweroff will be forced, otherwise it will be gracefully,"
 | 
| 48 | 50 |    print "    which may take some time."
 | 
| 49 | 51 |    print ""
 | 
|   | 52 | +  print ""
 | 
|   | 53 | +  print "  uploadfile <offset> <file> <usedma> <freezescheduler>"
 | 
|   | 54 | +  print "    Uploads a file to the iPod"
 | 
|   | 55 | +  print "      <offset>: the address to upload the file to"
 | 
|   | 56 | +  print "      <file>: the path to the file"
 | 
|   | 57 | +  print "      <usedma>: if 0, DMA will not be used when uploading the file,"
 | 
|   | 58 | +  print "          otherwise it will be used. It can be omitted, default is then 1"
 | 
|   | 59 | +  print "      <freezescheduler>: if not 0, the scheduler will be frozen during DMA access"
 | 
|   | 60 | +  print "          to prevent non-consistent data after the transfer."
 | 
|   | 61 | +  print "          It can be omitted, default is then 0"
 | 
|   | 62 | +  print ""
 | 
|   | 63 | +  print "  downloadfile <offset> <size> <file> <usedma> <freezescheduler>"
 | 
|   | 64 | +  print "    Uploads a file to the iPod"
 | 
|   | 65 | +  print "      <offset>: the address to upload the file to"
 | 
|   | 66 | +  print "      <size>: the number of bytes to be read"
 | 
|   | 67 | +  print "      <file>: the path to the file"
 | 
|   | 68 | +  print "      <usedma>: if 0, DMA will not be used when downloading the file,"
 | 
|   | 69 | +  print "          otherwise it will be used. It can be omitted, default is then 1"
 | 
|   | 70 | +  print "      <freezescheduler>: if not 0, the scheduler will be frozen during DMA access"
 | 
|   | 71 | +  print "          to prevent non-consistent data after the transfer"
 | 
|   | 72 | +  print "          It can be omitted, default is then 0"
 | 
|   | 73 | +  print ""
 | 
|   | 74 | +  print "  uploadint <offset> <data>"
 | 
|   | 75 | +  print "    Uploads a single integer to the iPod"
 | 
|   | 76 | +  print "      <offset>: the address to upload the integer to"
 | 
|   | 77 | +  print "      <data>: the integer to upload"
 | 
|   | 78 | +  print ""
 | 
|   | 79 | +  print "  downloadint <offset>"
 | 
|   | 80 | +  print "    Downloads a single integer from the iPod and prints it to the console window"
 | 
|   | 81 | +  print "      <offset>: the address to download the integer from"
 | 
|   | 82 | +  print ""
 | 
|   | 83 | +  print ""
 | 
| 50 | 84 |    print "  i2crecv <bus> <slave> <addr> <size>"
 | 
| 51 | 85 |    print "    Reads data from an I2C device"
 | 
| 52 | 86 |    print "      <bus> the bus index"
 | 
| — | — | @@ -58,8 +92,49 @@ | 
| 59 | 93 |    print "      <bus> the bus index"
 | 
| 60 | 94 |    print "      <slave> the slave address"
 | 
| 61 | 95 |    print "      <addr> the start address on the I2C device"
 | 
| 62 |   | -  print "      <db1> ... <dbN> the data in single bytes, seperated by whitespaces, eg. 0x37 0x56 0x45 0x12"
 | 
|   | 96 | +  print "      <db1> ... <dbN> the data in single bytes, seperated by whitespaces,"
 | 
|   | 97 | +  print "                      eg. 0x37 0x56 0x45 0x12"
 | 
| 63 | 98 |    print ""
 | 
|   | 99 | +  print ""
 | 
|   | 100 | +  print "  readusbconsole <size> <outtype> <file>"
 | 
|   | 101 | +  print "    Reads data from the USB console."
 | 
|   | 102 | +  print "      <size>: the number of bytes to read"
 | 
|   | 103 | +  print "      <outtype>: defines how to output the result:"
 | 
|   | 104 | +  print "        'file': writes the result to file <file>"
 | 
|   | 105 | +  print "        'printstring': writes the result as string to the console window"
 | 
|   | 106 | +  print "        'printhex': writes the result in hexedit notation to the console window"
 | 
|   | 107 | +  print "      <file>: the file to write the result to, can be omitted"
 | 
|   | 108 | +  print "               if <outtype> is not 'file'"
 | 
|   | 109 | +  print ""
 | 
|   | 110 | +  print "  writeusbconsole file <file> <offset> <length>"
 | 
|   | 111 | +  print "    Writes the file <file> to the USB console."
 | 
|   | 112 | +  print "      Optional params <offset> <length>: specify the range in <file> to write"
 | 
|   | 113 | +  print "  writeusbconsole direct <i1> <i2> ... <iN>"
 | 
|   | 114 | +  print "    Writes the integers <i1> ... <iN> to the USB console."
 | 
|   | 115 | +  print ""
 | 
|   | 116 | +  print "  readdevconsole <bitmask> <size> <outtype> <file>"
 | 
|   | 117 | +  print "    Reads data from one or more of the device's consoles."
 | 
|   | 118 | +  print "      <bitmask>: the bitmask of the consoles to read from"
 | 
|   | 119 | +  print "      <size>: the number of bytes to read"
 | 
|   | 120 | +  print "      <outtype>: defines how to output the result:"
 | 
|   | 121 | +  print "        'file': writes the result to file <file>"
 | 
|   | 122 | +  print "        'printstring': writes the result as string to the console window"
 | 
|   | 123 | +  print "        'printhex': writes the result in hexedit notation to the console window"
 | 
|   | 124 | +  print "      <file>: the file to write the result to, can be omitted"
 | 
|   | 125 | +  print "               if <outtype> is not 'file'"
 | 
|   | 126 | +  print ""
 | 
|   | 127 | +  print "  writedevconsole file <bitmask> <file> <offset> <length>"
 | 
|   | 128 | +  print "    Writes the file <file> to the device consoles specified by <bitmask>"
 | 
|   | 129 | +  print "      Optional params <offset> <length>: specify the range in <file> to write"
 | 
|   | 130 | +  print "  writedevconsole direct <bitmask> <i1> <i2> ... <iN>"
 | 
|   | 131 | +  print "    Writes the integers <i1> ... <iN> to the device consoles specified"
 | 
|   | 132 | +  print "                         by <bitmask>"
 | 
|   | 133 | +  print ""
 | 
|   | 134 | +  print "  flushconsolebuffers <bitmask>"
 | 
|   | 135 | +  print "    flushes one or more of the device consoles' buffers."
 | 
|   | 136 | +  print "      <bitmask>: the bitmask of the consoles to be flushed"
 | 
|   | 137 | +  print ""
 | 
|   | 138 | +  print ""
 | 
| 64 | 139 |    print "  getprocessinformation <offset> <size> / getprocinfo <offset> <size>"
 | 
| 65 | 140 |    print "    Fetches data on the currently running processes"
 | 
| 66 | 141 |    print "      <offset> the offset in the data field"
 | 
| — | — | @@ -93,6 +168,7 @@ | 
| 94 | 169 |    print "      <priority> the priority of the thread, from 1 to 255"
 | 
| 95 | 170 |    print "      <state> the thread's initial state, valid are: 1 => ready, 0 => suspended"
 | 
| 96 | 171 |    print ""
 | 
|   | 172 | +  print ""
 | 
| 97 | 173 |    print "  flushcaches"
 | 
| 98 | 174 |    print "    Flushes the CPUs data and instruction caches."
 | 
| 99 | 175 |    print ""
 | 
| — | — | @@ -115,6 +191,42 @@ | 
| 116 | 192 |      if len(argv) != 3: usage()
 | 
| 117 | 193 |      dev.poweroff(int(argv[2]))
 | 
| 118 | 194 |  
 | 
|   | 195 | +    
 | 
|   | 196 | +  elif argv[1] == "uploadfile":
 | 
|   | 197 | +    if len(argv) < 4 or len(argv) > 6: usage()
 | 
|   | 198 | +    if len(argv) > 4:
 | 
|   | 199 | +      usedma = argv[4]
 | 
|   | 200 | +      if len(argv) > 5:
 | 
|   | 201 | +        freezesched = argv[5]
 | 
|   | 202 | +      else:
 | 
|   | 203 | +        freezesched = 0
 | 
|   | 204 | +    else:
 | 
|   | 205 | +      freezesched = 0
 | 
|   | 206 | +      usedma = 1
 | 
|   | 207 | +    dev.uploadfile(int(argv[2]), argv[3], usedma, freezesched)
 | 
|   | 208 | +  
 | 
|   | 209 | +  elif argv[1] == "downloadfile":
 | 
|   | 210 | +    if len(argv) < 5 or len(argv) > 7: usage()
 | 
|   | 211 | +    if len(argv) > 5:
 | 
|   | 212 | +      usedma = argv[5]
 | 
|   | 213 | +      if len(argv) > 6:
 | 
|   | 214 | +        freezesched = argv[6]
 | 
|   | 215 | +      else:
 | 
|   | 216 | +        freezesched = 0
 | 
|   | 217 | +    else:
 | 
|   | 218 | +      freezesched = 0
 | 
|   | 219 | +      usedma = 1
 | 
|   | 220 | +    dev.downloadfile(int(argv[2]), int(argv[3]), argv[4], usedma, freezesched)
 | 
|   | 221 | +  
 | 
|   | 222 | +  elif argv[1] == "uploadint":
 | 
|   | 223 | +    if len(argv) != 4: usage()
 | 
|   | 224 | +    dev.uploadint(int(argv[2]), int(argv[3]))
 | 
|   | 225 | +  
 | 
|   | 226 | +  elif argv[1] == "downloadint":
 | 
|   | 227 | +    if len(argv) != 3: usage()
 | 
|   | 228 | +    dev.downloadint(int(argv[2]))
 | 
|   | 229 | +  
 | 
|   | 230 | +  
 | 
| 119 | 231 |    elif argv[1] == "i2cread":
 | 
| 120 | 232 |      if len(argv) != 6: usage()
 | 
| 121 | 233 |      dev.i2crecv(int(argv[2]), int(argv[3]), int(argv[4]), int(argv[5]))
 | 
| — | — | @@ -127,7 +239,77 @@ | 
| 128 | 240 |        data += struct.pack("<B", int(argv[ptr]))
 | 
| 129 | 241 |        ptr += 1
 | 
| 130 | 242 |      dev.i2csend(int(argv[2]), int(argv[3]), int(argv[4]), data)
 | 
|   | 243 | +  
 | 
|   | 244 | +  
 | 
|   | 245 | +  elif argv[1] == "readusbconsole":
 | 
|   | 246 | +    if len(argv) not in [4, 5]: usage()
 | 
|   | 247 | +    if len(argv) == 4: argv[4] = ""
 | 
|   | 248 | +    dev.readusbcon(int(argv[2]), argv[3], argv[4])
 | 
|   | 249 | +  
 | 
|   | 250 | +  elif argv[1] == "writeusbconsole":
 | 
|   | 251 | +    if len(argv) < 4: usage()
 | 
| 131 | 252 |      
 | 
|   | 253 | +    if argv[2] == "file":
 | 
|   | 254 | +      f = open(argv[3], "rb")
 | 
|   | 255 | +      data = f.read()
 | 
|   | 256 | +      
 | 
|   | 257 | +      if len(argv) > 4:
 | 
|   | 258 | +        offset = int(argv[4])
 | 
|   | 259 | +      else:
 | 
|   | 260 | +        offset = 0
 | 
|   | 261 | +      if len(argv) > 5:
 | 
|   | 262 | +        size = int(argv[5])
 | 
|   | 263 | +      else:
 | 
|   | 264 | +        size = len(data)
 | 
|   | 265 | +      if len(argv) > 6: usage()
 | 
|   | 266 | +      
 | 
|   | 267 | +      dev.writeusbcon(data, 0, offset, size)
 | 
|   | 268 | +      
 | 
|   | 269 | +    if argv[2] == "direct":
 | 
|   | 270 | +      data = ""
 | 
|   | 271 | +      ptr = 3
 | 
|   | 272 | +      while ptr < len(argv):
 | 
|   | 273 | +        data += struct.pack("<I", int(argv[ptr]))
 | 
|   | 274 | +        ptr += 1
 | 
|   | 275 | +      dev.writeusbcon(data)
 | 
|   | 276 | +  
 | 
|   | 277 | +  elif argv[1] == "readdevconsole":
 | 
|   | 278 | +    if len(argv) not in [5, 6]: usage()
 | 
|   | 279 | +    if len(argv) == 5: argv[5] = ""
 | 
|   | 280 | +    dev.readusbcon(int(argv[2]), int(argv[3]), argv[4], argv[5])
 | 
|   | 281 | +  
 | 
|   | 282 | +  elif argv[1] == "writedevconsole":
 | 
|   | 283 | +    if len(argv) < 5: usage()
 | 
|   | 284 | +    
 | 
|   | 285 | +    if argv[2] == "file":
 | 
|   | 286 | +      f = open(argv[4], "rb")
 | 
|   | 287 | +      data = f.read()
 | 
|   | 288 | +      
 | 
|   | 289 | +      if len(argv) > 5:
 | 
|   | 290 | +        offset = int(argv[5])
 | 
|   | 291 | +      else:
 | 
|   | 292 | +        offset = 0
 | 
|   | 293 | +      if len(argv) > 6:
 | 
|   | 294 | +        size = int(argv[6])
 | 
|   | 295 | +      else:
 | 
|   | 296 | +        size = len(data)
 | 
|   | 297 | +      if len(argv) > 7: usage()
 | 
|   | 298 | +      
 | 
|   | 299 | +      dev.writeusbcon(int(argv[3]), data, 0, offset, size)
 | 
|   | 300 | +      
 | 
|   | 301 | +    if argv[2] == "direct":
 | 
|   | 302 | +      data = ""
 | 
|   | 303 | +      ptr = 4
 | 
|   | 304 | +      while ptr < len(argv):
 | 
|   | 305 | +        data += struct.pack("<I", int(argv[ptr]))
 | 
|   | 306 | +        ptr += 1
 | 
|   | 307 | +      dev.writeusbcon(int(argv[3]), data)
 | 
|   | 308 | +  
 | 
|   | 309 | +  elif argv[1] == "flushconsolebuffers":
 | 
|   | 310 | +    if len(argv) != 3: usage()
 | 
|   | 311 | +    dev.flushconsolebuffers(int(argv[2]))
 | 
|   | 312 | +   
 | 
|   | 313 | +   
 | 
| 132 | 314 |    elif argv[1] == "getprocessinformation" or argv[1] == "getprocinfo":
 | 
| 133 | 315 |      if len(argv) != 4: usage()
 | 
| 134 | 316 |      dev.getprocinfo(int(argv[2]), int(argv[3]))
 | 
| — | — | @@ -156,6 +338,7 @@ | 
| 157 | 339 |      if len(argv) != 9: usage()
 | 
| 158 | 340 |      dev.createthread(int(argv[2]), int(argv[3]), int(argv[4]), int(argv[5]), int(argv[6]), int(argv[7]), int(argv[8]))
 | 
| 159 | 341 |      
 | 
|   | 342 | +    
 | 
| 160 | 343 |    elif argv[1] == "flushcaches":
 | 
| 161 | 344 |      if len(argv) != 2: usage()
 | 
| 162 | 345 |      dev.flushcaches()
 | 
| Index: embios/trunk/tools/libembios.py | 
| — | — | @@ -21,7 +21,7 @@ | 
| 22 | 22 |  #
 | 
| 23 | 23 |  #
 | 
| 24 | 24 |  
 | 
| 25 |   | -# note: handles commands 1,2,3,4,5,6,7,8,9,10,11,   ,14,15,16,17,18,19,20
 | 
|   | 25 | +# note: handles commands 1 to 20
 | 
| 26 | 26 |  
 | 
| 27 | 27 |  import sys
 | 
| 28 | 28 |  import math
 | 
| — | — | @@ -59,7 +59,7 @@ | 
| 60 | 60 |              self.handle = handle
 | 
| 61 | 61 |              self.dev = dev
 | 
| 62 | 62 |              
 | 
| 63 |   | -            self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
 | 
|   | 63 | +            self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]
 | 
| 64 | 64 |              self.__myprint("Connected to emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
 | 
| 65 | 65 |                    % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
 | 
| 66 | 66 |                       self.devtype2name(self.devtype), dev.deviceVersion))
 | 
| — | — | @@ -80,7 +80,7 @@ | 
| 81 | 81 |      
 | 
| 82 | 82 |    @staticmethod
 | 
| 83 | 83 |    def __myprint(data, silent = 0):
 | 
| 84 |   | -    if (silent == 0):
 | 
|   | 84 | +    if not silent:
 | 
| 85 | 85 |        sys.stdout.write(data)
 | 
| 86 | 86 |        sys.stdout.flush()
 | 
| 87 | 87 |  
 | 
| — | — | @@ -157,7 +157,7 @@ | 
| 158 | 158 |        
 | 
| 159 | 159 |        i = struct.unpack("<IIBBBBI", response)
 | 
| 160 | 160 |        
 | 
| 161 |   | -      self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
 | 
|   | 161 | +      self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]
 | 
| 162 | 162 |        
 | 
| 163 | 163 |        self.__myprint("emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
 | 
| 164 | 164 |                % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
 | 
| — | — | @@ -459,7 +459,7 @@ | 
| 460 | 460 |  
 | 
| 461 | 461 |    def readusbcon(self, size, outtype = "", file = "", silent = 0):
 | 
| 462 | 462 |      """ reads from USB console
 | 
| 463 |   | -      <size>: number of bytes to be read, cannot be more than the Command In endpoint packet size - 0x10
 | 
|   | 463 | +      <size>: number of bytes to be read, if its length exceeds the Command In endpoint packet size - 0x10, it will be read in several steps
 | 
| 464 | 464 |        <outtype>: how the data will be put out
 | 
| 465 | 465 |          "file" => writes data to file <file>
 | 
| 466 | 466 |          "printstring" => prints data as a string to the console window
 | 
| — | — | @@ -471,51 +471,67 @@ | 
| 472 | 472 |          [len, buffersize, datainbuffer, data]
 | 
| 473 | 473 |            where len is the length of the data actually read,
 | 
| 474 | 474 |                  buffersize is the on-device read buffer size,
 | 
| 475 |   | -                datainbuffer is the number of bytes still left in the on_device buffer,
 | 
|   | 475 | +                datainbuffer is the number of bytes still left in the on device buffer,
 | 
| 476 | 476 |                  data is the actual data
 | 
|   | 477 | +      
 | 
|   | 478 | +      in case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur
 | 
| 477 | 479 |      """
 | 
| 478 |   | -    if size > self.cin_maxsize - 0x10:
 | 
| 479 |   | -      size = self.cin_maxsize - 0x10
 | 
|   | 480 | +    out_data = ""
 | 
|   | 481 | +    readbytes = 0
 | 
|   | 482 | +    buffersize = 0
 | 
|   | 483 | +    bytesleft = 0
 | 
|   | 484 | +    timeoutcounter = 0
 | 
| 480 | 485 |      
 | 
| 481 | 486 |      self.__myprint("Reading 0x%x bytes from USB console..." % (size), silent)
 | 
| 482 | 487 |      
 | 
| 483 |   | -    self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 10, size, 0, 0))
 | 
| 484 |   | -    response = self.__getbulk(self.handle, self.__cinep, size + 0x10)
 | 
| 485 |   | -    self.__checkstatus(response)
 | 
|   | 488 | +    while size > 0 and timoutcounter < 50:
 | 
|   | 489 | +      blocklen = size
 | 
|   | 490 | +      
 | 
|   | 491 | +      if size > self.cin_maxsize - 0x10:
 | 
|   | 492 | +        blocklen = self.cin_maxsize - 0x10
 | 
|   | 493 | +      
 | 
|   | 494 | +      self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 10, blocklen, 0, 0))
 | 
|   | 495 | +      response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)
 | 
|   | 496 | +      self.__checkstatus(response)
 | 
|   | 497 | +      
 | 
|   | 498 | +      readbytes, buffersize, bytesleft = struct.unpack("<III", response[:12])
 | 
|   | 499 | +      out_data += response[0x10:0x10+readbytes]
 | 
|   | 500 | +      size -= blocklen
 | 
|   | 501 | +      
 | 
|   | 502 | +      if not bytesleft > 0:   # no data left to read => wait a bit and prevent an infinite loop trying to read data when there is none
 | 
|   | 503 | +        timeoutcounter += 1
 | 
|   | 504 | +        time.sleep(0.1)
 | 
|   | 505 | +      else:
 | 
|   | 506 | +        timeoutcounter -= 3
 | 
|   | 507 | +        if timeoutcounter < 0:
 | 
|   | 508 | +          timeoutcounter = 0
 | 
|   | 509 | +          
 | 
|   | 510 | +    self.__myprint(" done\n", silent)
 | 
|   | 511 | +    self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
 | 
|   | 512 | +                    % (len(out_data), buffersize, bytesleft)                      
 | 
|   | 513 | +                    , silent)
 | 
| 486 | 514 |      
 | 
| 487 | 515 |      if (outtype == "file"):
 | 
| 488 | 516 |        f = open(file, "wb")
 | 
| 489 |   | -      f.write(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]])
 | 
|   | 517 | +      f.write(out_data)
 | 
| 490 | 518 |        
 | 
| 491 | 519 |      elif (outtype == "printstring"):
 | 
| 492 |   | -      self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
 | 
| 493 |   | -                    % (struct.unpack("<IIII", response[:0x10])[1], 
 | 
| 494 |   | -                       struct.unpack("<IIII", response[:0x10])[2],
 | 
| 495 |   | -                       struct.unpack("<IIII", response[:0x10])[3])
 | 
| 496 |   | -                    , silent)
 | 
| 497 |   | -      self.__myprint(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]], silent)
 | 
|   | 520 | +      self.__myprint(out_data, silent)
 | 
| 498 | 521 |        self.__myprint("\n\n", silent)
 | 
| 499 | 522 |        
 | 
| 500 | 523 |      elif (outtype == "printhex"):
 | 
| 501 |   | -      self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
 | 
| 502 |   | -                    % (struct.unpack("<IIII", response[:0x10])[1], 
 | 
| 503 |   | -                       struct.unpack("<IIII", response[:0x10])[2],
 | 
| 504 |   | -                       struct.unpack("<IIII", response[:0x10])[3])
 | 
| 505 |   | -                    , silent)
 | 
| 506 |   | -      self.__myprint(self.__gethexviewprintout(response[0x10:], "", 1), silent)
 | 
|   | 524 | +      self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)
 | 
| 507 | 525 |        self.__myprint("\n\n", silent)
 | 
| 508 | 526 |      
 | 
| 509 | 527 |      elif (outtype == ""):
 | 
| 510 | 528 |        pass    # return only
 | 
|   | 529 | +      
 | 
| 511 | 530 |      else:
 | 
| 512 | 531 |        raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))
 | 
| 513 | 532 |      
 | 
| 514 |   | -    self.__myprint(" done\n", silent)
 | 
|   | 533 | +    return [len(out_data), buffersize, bytesleft, out_data]
 | 
| 515 | 534 |      
 | 
| 516 |   | -    #      header                                         data
 | 
| 517 |   | -    return struct.unpack("<IIII", response[:0x10]).extend(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]])
 | 
| 518 | 535 |      
 | 
| 519 |   | -    
 | 
| 520 | 536 |    def writeusbcon(self, data, silent = 0, *range):
 | 
| 521 | 537 |      """ writes to USB console
 | 
| 522 | 538 |        <data>: the data to be written
 | 
| — | — | @@ -522,7 +538,7 @@ | 
| 523 | 539 |        <range>: the range in <data> that should be written, in the from [offset, length]
 | 
| 524 | 540 |        <silent>: if 0, nothing will be written to the console window
 | 
| 525 | 541 |        
 | 
| 526 |   | -      the data to be written can't exceed the Command Out endpoint packet size - 0x10
 | 
|   | 542 | +      if the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps
 | 
| 527 | 543 |      """
 | 
| 528 | 544 |      size = len(data)
 | 
| 529 | 545 |      boffset = 0
 | 
| — | — | @@ -532,30 +548,143 @@ | 
| 533 | 549 |      if len(range) > 1:
 | 
| 534 | 550 |        size = range[1]
 | 
| 535 | 551 |      
 | 
| 536 |   | -    if size > self.cout_maxsize - 0x10:
 | 
| 537 |   | -      size = self.cout_maxsize - 0x10
 | 
| 538 |   | -    
 | 
| 539 | 552 |      self.__myprint("Writing 0x%x bytes to USB console..." % (size), silent)
 | 
| 540 | 553 |      
 | 
| 541 | 554 |      timeoutcounter = 0
 | 
| 542 | 555 |      
 | 
| 543 |   | -    while (size != 0) and (timeoutcounter < 10):
 | 
| 544 |   | -      self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 11, size, 0, 0) + data[boffset:boffset+size])
 | 
|   | 556 | +    while (size > 0) and (timeoutcounter < 50):
 | 
|   | 557 | +      blocklen = size
 | 
|   | 558 | +      if blocklen > self.cout_maxsize - 0x10:
 | 
|   | 559 | +        blocklen = self.cout_maxsize - 0x10
 | 
|   | 560 | +    
 | 
|   | 561 | +      self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 11, size, 0, 0) + data[boffset:boffset+blocklen])
 | 
| 545 | 562 |        response = self.__getbulk(self.handle, self.__cinep, 0x10)
 | 
| 546 | 563 |        self.__checkstatus(response)
 | 
| 547 | 564 |        
 | 
| 548 |   | -      size -= struct.unpack("<I", response[4:8])
 | 
| 549 |   | -      boffset += struct.unpack("<I", response[4:8])
 | 
|   | 565 | +      sendbytes = struct.unpack("<I", response[4:8])
 | 
|   | 566 | +      if sendbytes < blocklen:   # not everything has been written, need to resent some stuff but wait a bit before doing so
 | 
|   | 567 | +        time.sleep(0.1)
 | 
|   | 568 | +        timeoutcounter += 1
 | 
|   | 569 | +      elif timeoutcounter > 0:    # lower timeoutcounter again
 | 
|   | 570 | +        timeoutcounter -= 3
 | 
|   | 571 | +        if timeoutcounter < 0:
 | 
|   | 572 | +          timeoutcounter = 0
 | 
| 550 | 573 |        
 | 
| 551 |   | -      time.sleep(0.1)
 | 
| 552 |   | -      timeoutcounter += 1
 | 
|   | 574 | +      size -= sendbytes
 | 
|   | 575 | +      boffset += sendbytes
 | 
|   | 576 | +
 | 
| 553 | 577 |        
 | 
| 554 |   | -    if (timeoutcounter >=10):
 | 
| 555 |   | -      raise Exception("0x%x couldn't be send.")
 | 
|   | 578 | +    if (timeoutcounter >=50):
 | 
|   | 579 | +      raise Exception("Timeout, 0x%x bytes couldn't be send." % size)
 | 
| 556 | 580 |      
 | 
| 557 | 581 |      self.__myprint(" done\n", silent)
 | 
| 558 | 582 |      
 | 
|   | 583 | +    return size   # number of bytes that have not been sent
 | 
|   | 584 | +    
 | 
| 559 | 585 |  
 | 
|   | 586 | +  def readdevcon(self, bitmask, size, outtype = "", file = "", silent = 0):
 | 
|   | 587 | +    """ reads from one or more of the device's consoles
 | 
|   | 588 | +      <bitmask>: bitmask of consoles to be read from
 | 
|   | 589 | +      <size>: number of bytes to be read, if its length exceeds the Command In endpoint packet size - 0x10, it will be read in several steps
 | 
|   | 590 | +      <outtype>: how the data will be put out
 | 
|   | 591 | +        "file" => writes data to file <file>
 | 
|   | 592 | +        "printstring" => prints data as a string to the console window
 | 
|   | 593 | +        "printhex" => prints a hexview view of the data to the console window
 | 
|   | 594 | +        "" => only returns the data
 | 
|   | 595 | +      <silent>: if 0, nothing will be written to the console window (even if <outtype> defines something else)
 | 
|   | 596 | +      
 | 
|   | 597 | +      in every case, the data will be returned
 | 
|   | 598 | +      
 | 
|   | 599 | +      in case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur
 | 
|   | 600 | +    """
 | 
|   | 601 | +    out_data = ""
 | 
|   | 602 | +    readbytes = 0
 | 
|   | 603 | +    timeoutcounter = 0
 | 
|   | 604 | +    
 | 
|   | 605 | +    self.__myprint("Reading 0x%x bytes from device's console(s)..." % (size), silent)
 | 
|   | 606 | +    
 | 
|   | 607 | +    while size > 0 and timoutcounter < 50:
 | 
|   | 608 | +      blocklen = size
 | 
|   | 609 | +      
 | 
|   | 610 | +      if size > self.cin_maxsize - 0x10:
 | 
|   | 611 | +        blocklen = self.cin_maxsize - 0x10
 | 
|   | 612 | +      
 | 
|   | 613 | +      self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 13, bitmask, blocklen, 0))
 | 
|   | 614 | +      response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)
 | 
|   | 615 | +      self.__checkstatus(response)
 | 
|   | 616 | +      
 | 
|   | 617 | +      readbytes = struct.unpack("<III", response[4:8])
 | 
|   | 618 | +      out_data += response[0x10:0x10+readbytes]
 | 
|   | 619 | +      size -= blocklen
 | 
|   | 620 | +      
 | 
|   | 621 | +      if not readbytes > 0:   # no data read => wait a bit and prevent an infinite loop trying to read data when there is none
 | 
|   | 622 | +        timeoutcounter += 1
 | 
|   | 623 | +        time.sleep(0.1)
 | 
|   | 624 | +      else:
 | 
|   | 625 | +        timeoutcounter -= 3
 | 
|   | 626 | +        if timeoutcounter < 0:
 | 
|   | 627 | +          timeoutcounter = 0
 | 
|   | 628 | +          
 | 
|   | 629 | +    self.__myprint(" done\n", silent)
 | 
|   | 630 | +    self.__myprint("\nBytes read: 0x%x\n\n" % (len(out_data)), silent)
 | 
|   | 631 | +    
 | 
|   | 632 | +    if (outtype == "file"):
 | 
|   | 633 | +      f = open(file, "wb")
 | 
|   | 634 | +      f.write(out_data)
 | 
|   | 635 | +      
 | 
|   | 636 | +    elif (outtype == "printstring"):
 | 
|   | 637 | +      self.__myprint(out_data, silent)
 | 
|   | 638 | +      self.__myprint("\n\n", silent)
 | 
|   | 639 | +      
 | 
|   | 640 | +    elif (outtype == "printhex"):
 | 
|   | 641 | +      self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)
 | 
|   | 642 | +      self.__myprint("\n\n", silent)
 | 
|   | 643 | +    
 | 
|   | 644 | +    elif (outtype == ""):
 | 
|   | 645 | +      pass    # return only
 | 
|   | 646 | +      
 | 
|   | 647 | +    else:
 | 
|   | 648 | +      raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))
 | 
|   | 649 | +    
 | 
|   | 650 | +    return out_data
 | 
|   | 651 | +    
 | 
|   | 652 | +    
 | 
|   | 653 | +  def writedevcon(self, bitmask, data, silent = 0, *range):
 | 
|   | 654 | +    """ writes to USB console
 | 
|   | 655 | +      <bitmask>: bitmask of consoles to be written to
 | 
|   | 656 | +      <data>: the data to be written
 | 
|   | 657 | +      <range>: the range in <data> that should be written, in the from [offset, length]
 | 
|   | 658 | +      <silent>: if 0, nothing will be written to the console window
 | 
|   | 659 | +      
 | 
|   | 660 | +      if the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps
 | 
|   | 661 | +    """
 | 
|   | 662 | +    size = len(data)
 | 
|   | 663 | +    boffset = 0
 | 
|   | 664 | +    
 | 
|   | 665 | +    if len(range) > 0:
 | 
|   | 666 | +      boffset = range[0]
 | 
|   | 667 | +    if len(range) > 1:
 | 
|   | 668 | +      size = range[1]
 | 
|   | 669 | +    
 | 
|   | 670 | +    self.__myprint("Writing 0x%x bytes to device's console(s)..." % (size), silent)
 | 
|   | 671 | +    
 | 
|   | 672 | +    timeoutcounter = 0
 | 
|   | 673 | +    
 | 
|   | 674 | +    while size > 0:
 | 
|   | 675 | +      blocklen = size
 | 
|   | 676 | +      if blocklen > self.cout_maxsize - 0x10:
 | 
|   | 677 | +        blocklen = self.cout_maxsize - 0x10
 | 
|   | 678 | +    
 | 
|   | 679 | +      self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 12, bitmask, size, 0) + data[boffset:boffset+blocklen])
 | 
|   | 680 | +      response = self.__getbulk(self.handle, self.__cinep, 0x10)
 | 
|   | 681 | +      self.__checkstatus(response)
 | 
|   | 682 | +      
 | 
|   | 683 | +      size -= blocklen
 | 
|   | 684 | +      boffset += blocklen
 | 
|   | 685 | +    
 | 
|   | 686 | +    self.__myprint(" done\n", silent)
 | 
|   | 687 | +   
 | 
|   | 688 | +       
 | 
| 560 | 689 |    def flushconsolebuffers(self, bitmask, silent = 0):
 | 
| 561 | 690 |      self.__myprint("Flushing device console('s) buffer('s)...")
 | 
| 562 | 691 |      
 | 
| — | — | @@ -867,6 +996,8 @@ | 
| 868 | 997 |          processinfoprint += "priority: 0x%02x      " % (out[i+3]['priority'])
 | 
| 869 | 998 |          processinfoprint += "cpu load: 0x%02x\n" % (out[i+3]['cpuload'])
 | 
| 870 | 999 |          
 | 
|   | 1000 | +        i += 1
 | 
|   | 1001 | +        
 | 
| 871 | 1002 |      except IndexError:
 | 
| 872 | 1003 |        processinfoprint += "--------------------------------------------------------------------------------"
 | 
| 873 | 1004 |      
 | 
| — | — | @@ -895,7 +1026,7 @@ | 
| 896 | 1027 |      
 | 
| 897 | 1028 |    
 | 
| 898 | 1029 |  #======================================================================================
 | 
| 899 |   | -#======================================================================================
 | 
|   | 1030 | +# backlight control, remnant from libibugger adjusted to work with libembios ==========
 | 
| 900 | 1031 |  
 | 
| 901 | 1032 |  
 | 
| 902 | 1033 |    def backlighton(self, fade, brightness, silent = 0):
 |