| Index: embios/trunk/tools/embios.py | 
| — | — | @@ -25,7 +25,10 @@ | 
| 26 | 26 | import os | 
| 27 | 27 | import inspect | 
| 28 | 28 | import re | 
|  | 29 | +import time | 
| 29 | 30 |  | 
|  | 31 | +from functools import wraps | 
|  | 32 | + | 
| 30 | 33 | import libembios | 
| 31 | 34 | from libembios import Error | 
| 32 | 35 | import libembiosdata | 
| — | — | @@ -144,6 +147,7 @@ | 
| 145 | 148 | Decorator for all commands. | 
| 146 | 149 | The decorated function is called with (self, all, other, arguments, ...) | 
| 147 | 150 | """ | 
|  | 151 | +    @wraps(func) | 
| 148 | 152 | def decorator(*args): | 
| 149 | 153 | return func(args[0], *args[1:]) | 
| 150 | 154 | func._command = True | 
| — | — | @@ -179,12 +183,8 @@ | 
| 180 | 184 | self.embios = libembios.Embios() | 
| 181 | 185 | except libembios.DeviceNotFoundError: | 
| 182 | 186 | self.logger.error("No emBIOS device found!") | 
| 183 |  | -            end(1)
 | 
| 184 |  | -        try:
 | 
| 185 |  | -            self.getinfo("version")
 | 
| 186 |  | -        except libembios.DeviceNotFoundError:
 | 
| 187 |  | -                self.logger.error("Device not found!")
 | 
| 188 |  | -                exit(2)
 | 
|  | 187 | +            exit(1) | 
|  | 188 | +        self.getinfo("version") | 
| 189 | 189 |  | 
| 190 | 190 | def _parsecommand(self, func, args): | 
| 191 | 191 | # adds self to the commandline args. | 
| — | — | @@ -194,20 +194,24 @@ | 
| 195 | 195 | try: | 
| 196 | 196 | self.cmddict[func](*args) | 
| 197 | 197 | except ArgumentError, e: | 
| 198 |  | -                usage(e)
 | 
|  | 198 | +                usage(e, specific=func) | 
| 199 | 199 | except ArgumentError: | 
| 200 |  | -                usage("Syntax Error in function '" + func + "'")
 | 
|  | 200 | +                usage("Syntax Error in function '" + func + "'", specific=func) | 
| 201 | 201 | except ArgumentTypeError, e: | 
| 202 |  | -                usage(e)
 | 
|  | 202 | +                usage(e, specific=func) | 
| 203 | 203 | except NotImplementedError: | 
| 204 | 204 | self.logger.error("This function is not implemented yet!") | 
| 205 | 205 | except libembios.DeviceError, e: | 
| 206 | 206 | self.logger.error(str(e)) | 
|  | 207 | +            except ValueError: | 
|  | 208 | +                usage(specific=func) | 
| 207 | 209 | except TypeError, e: | 
| 208 | 210 | if str(e).split(" ", 1)[0] == func + "()": | 
| 209 | 211 | self.logger.error(usage("Argument Error in '" + func + "': Wrong argument count", specific=func)) | 
| 210 | 212 | else: | 
| 211 | 213 | raise | 
|  | 214 | +            except libembios.usb.core.USBError: | 
|  | 215 | +                self.logger.error("Problem with USB connection.") | 
| 212 | 216 | else: | 
| 213 | 217 | usage("No such command") | 
| 214 | 218 |  | 
| — | — | @@ -322,9 +326,7 @@ | 
| 323 | 327 | with f: | 
| 324 | 328 | self.embios.write(addr, f.read()) | 
| 325 | 329 | self.logger.info("done\n") | 
| 326 |  | -        
 | 
| 327 |  | -        
 | 
| 328 |  | -
 | 
|  | 330 | + | 
| 329 | 331 | @command | 
| 330 | 332 | def downloadfile(self, addr, size, filename): | 
| 331 | 333 | """ | 
| — | — | @@ -371,7 +373,7 @@ | 
| 372 | 374 | self.logger.info("Integer '"+self._hex(integer)+"' read from address "+self._hex(addr)) | 
| 373 | 375 |  | 
| 374 | 376 | @command | 
| 375 |  | -    def i2crecv(self, bus, slave, addr, size):
 | 
|  | 377 | +    def i2cread(self, bus, slave, addr, size): | 
| 376 | 378 | """ | 
| 377 | 379 | Reads data from an I2C device | 
| 378 | 380 | <bus> the bus index | 
| — | — | @@ -383,103 +385,75 @@ | 
| 384 | 386 | slave = self._hexint(slave) | 
| 385 | 387 | addr = self._hexint(addr) | 
| 386 | 388 | size = self._hexint(size) | 
| 387 |  | -        raise NotImplementedError
 | 
|  | 389 | +        self.embios.i2cread(bus, slave, addr, size) | 
| 388 | 390 |  | 
| 389 | 391 | @command | 
| 390 |  | -    def i2csend(self, bus, slave, addr, *args):
 | 
|  | 392 | +    def i2cwrite(self, bus, slave, addr, *args): | 
| 391 | 393 | """ | 
| 392 | 394 | Writes data to an I2C device | 
| 393 | 395 | <bus> the bus index | 
| 394 | 396 | <slave> the slave address | 
| 395 | 397 | <addr> the start address on the I2C device | 
| 396 |  | -            <db1> ... <dbN> the data in single bytes, seperated by whitespaces,
 | 
| 397 |  | -                eg. 0x37 0x56 0x45 0x12
 | 
|  | 398 | +            <db1> ... <dbN> the data in single bytes, encoded in hex, | 
|  | 399 | +                seperated by whitespaces, eg. 37 56 45 12 | 
| 398 | 400 | """ | 
| 399 | 401 | bus = self._hexint(bus) | 
| 400 | 402 | slave = self._hexint(slave) | 
| 401 | 403 | addr = self._hexint(addr) | 
| 402 |  | -        data = []
 | 
|  | 404 | +        data = "" | 
| 403 | 405 | for arg in args: | 
| 404 |  | -            data.append(self._hexint(arg))
 | 
| 405 |  | -        raise NotImplementedError
 | 
|  | 406 | +            data += chr(self._hexint(arg)) | 
|  | 407 | +        self.embios.i2cwrite(bus, slave, addr, data) | 
| 406 | 408 |  | 
| 407 | 409 | @command | 
| 408 |  | -    def readusbconsole(self, size, outtype):
 | 
|  | 410 | +    def console(self): | 
| 409 | 411 | """ | 
| 410 |  | -            Reads data from the USB console.
 | 
| 411 |  | -            <size>: the number of bytes to read
 | 
| 412 |  | -            <outtype>: defines how to output the result:
 | 
| 413 |  | -                'file': writes the result to file <file>
 | 
| 414 |  | -                'printstring': writes the result as string to the console window
 | 
| 415 |  | -                'printhex': writes the result in hexedit notation to the console window
 | 
| 416 |  | -            <file>: the file to write the result to, can be omitted
 | 
| 417 |  | -                if <outtype> is not 'file'
 | 
|  | 412 | +            Reads data from the USB console continuously | 
| 418 | 413 | """ | 
| 419 |  | -        size = self._hexint(size)
 | 
| 420 |  | -        raise NotImplementedError
 | 
| 421 |  | -        
 | 
|  | 414 | +        while True: | 
|  | 415 | +            resp = self.embios.usbcread() | 
|  | 416 | +            self.logger.log(resp.data) | 
|  | 417 | +            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data))) | 
| 422 | 418 |  | 
| 423 | 419 | @command | 
| 424 |  | -    def writeusbconsole_file(self, file, offset=0, length=None):
 | 
|  | 420 | +    def writeusbconsole(self, *args): | 
| 425 | 421 | """ | 
| 426 |  | -            Writes the file <file> to the USB console.
 | 
| 427 |  | -            Optional params <offset> <length>: specify the range in <file> to write
 | 
|  | 422 | +            Writes the string <db1> ... <dbN> to the USB console. | 
| 428 | 423 | """ | 
| 429 |  | -        
 | 
| 430 |  | -        offset = self._hexint(offset)
 | 
| 431 |  | -        length = self._hexint(length)
 | 
| 432 |  | -        raise NotImplementedError
 | 
|  | 424 | +        text = "" | 
|  | 425 | +        for word in args: | 
|  | 426 | +            text += word + " " | 
|  | 427 | +        text = text[:-1] | 
|  | 428 | +        self.logger.info("Writing '"+text+"' to the usb console\n") | 
|  | 429 | +        self.embios.usbcwrite(text) | 
| 433 | 430 |  | 
| 434 | 431 | @command | 
| 435 |  | -    def writeusbconsole_direct(self, *args):
 | 
|  | 432 | +    def readdevconsole(self, bitmask): | 
| 436 | 433 | """ | 
| 437 |  | -            Writes the strings <db1> ... <dbN> to the USB console."
 | 
|  | 434 | +            Reads data continuously from one or more of the device's consoles. | 
|  | 435 | +            <bitmask>: the bitmask of the consoles to read from. | 
| 438 | 436 | """ | 
| 439 |  | -        raise NotImplementedError
 | 
| 440 |  | -
 | 
| 441 |  | -    @command
 | 
| 442 |  | -    def readdevconsole(self, bitmask, size, outtype, file=None):
 | 
| 443 |  | -        """
 | 
| 444 |  | -            Reads data from one or more of the device's consoles.
 | 
| 445 |  | -            <bitmask>: the bitmask of the consoles to read from
 | 
| 446 |  | -            <size>: the number of bytes to read
 | 
| 447 |  | -            <outtype>: defines how to output the result:
 | 
| 448 |  | -                'file': writes the result to file <file>
 | 
| 449 |  | -                'printstring': writes the result as string to the console window
 | 
| 450 |  | -                'printhex': writes the result in hexedit notation to the console window
 | 
| 451 |  | -            <file>: the file to write the result to, can be omitted
 | 
| 452 |  | -                if <outtype> is not 'file'
 | 
| 453 |  | -        """
 | 
| 454 | 437 | bitmask = self._hexint(bitmask) | 
| 455 |  | -        size = self._hexint(size)
 | 
| 456 |  | -        outtype = self._strcheck(['file', 'printstring', 'printhex'])
 | 
| 457 |  | -        raise NotImplementedError
 | 
| 458 |  | -
 | 
|  | 438 | +        while True: | 
|  | 439 | +            resp = self.embios.cread() | 
|  | 440 | +            self.logger.log(resp.data) | 
|  | 441 | +            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data))) | 
|  | 442 | + | 
| 459 | 443 | @command | 
| 460 |  | -    def writedevconsole_file(self, bitmask, file, offset=0, length=None):
 | 
|  | 444 | +    def writedevconsole(self, bitmask, *args): | 
| 461 | 445 | """ | 
| 462 |  | -            Writes the file <file> to the device consoles specified by <bitmask>
 | 
| 463 |  | -            Optional params <offset> <length>: specify the range in <file> to write
 | 
|  | 446 | +            Writes the string <db1> ... <dbN> to one or more of the device's consoles. | 
|  | 447 | +            <bitmask>: the bitmask of the consoles to write to | 
| 464 | 448 | """ | 
| 465 | 449 | bitmask = self._hexint(bitmask) | 
| 466 |  | -        
 | 
| 467 |  | -        offset = self._hexint(offset)
 | 
| 468 |  | -        length = self._hexint(length)
 | 
| 469 |  | -        raise NotImplementedError
 | 
|  | 450 | +        text = "" | 
|  | 451 | +        for word in args: | 
|  | 452 | +            text += word + " " | 
|  | 453 | +        text = text[:-1] | 
|  | 454 | +        self.logger.info("Writing '"+text+"' to the device consoles identified with "+self._hex(bitmask)+"\n") | 
|  | 455 | +        self.embios.cwrite(text, bitmask) | 
| 470 | 456 |  | 
| 471 | 457 | @command | 
| 472 |  | -    def writedevconsole_direct(self, bitmask, *args):
 | 
| 473 |  | -        """
 | 
| 474 |  | -            Writes the integers <db1> ... <dbN> to the device consoles specified
 | 
| 475 |  | -            by <bitmask>
 | 
| 476 |  | -        """
 | 
| 477 |  | -        bitmask = self._hexint(bitmask)
 | 
| 478 |  | -        data = []
 | 
| 479 |  | -        for arg in args:
 | 
| 480 |  | -            data.append(self._hexint(arg))
 | 
| 481 |  | -        raise NotImplementedError
 | 
| 482 |  | -
 | 
| 483 |  | -    @command
 | 
| 484 | 458 | def flushconsolebuffers(self, bitmask): | 
| 485 | 459 | """ | 
| 486 | 460 | flushes one or more of the device consoles' buffers. | 
| — | — | @@ -515,6 +489,7 @@ | 
| 516 | 490 | """ | 
| 517 | 491 | Locks (freezes) the scheduler | 
| 518 | 492 | """ | 
|  | 493 | +        self.logger.info("Will now lock scheduler\n") | 
| 519 | 494 | self.embios.lockscheduler() | 
| 520 | 495 |  | 
| 521 | 496 | @command | 
| — | — | @@ -522,6 +497,7 @@ | 
| 523 | 498 | """ | 
| 524 | 499 | Unlocks (unfreezes) the scheduler | 
| 525 | 500 | """ | 
|  | 501 | +        self.logger.info("Will now unlock scheduler\n") | 
| 526 | 502 | self.embios.unlockscheduler() | 
| 527 | 503 |  | 
| 528 | 504 | @command | 
| — | — | @@ -573,19 +549,8 @@ | 
| 574 | 550 | Uploads the emBIOS application <filename> to | 
| 575 | 551 | the beginning of the user memory and executes it | 
| 576 | 552 | """ | 
| 577 |  | -        try:
 | 
| 578 |  | -            f = open(filename, "rb")
 | 
| 579 |  | -        except IOError:
 | 
| 580 |  | -            raise ArgumentError("File not readable. Does it exist?")
 | 
| 581 |  | -        data = self.embios.getusermemrange()
 | 
| 582 |  | -        addr = data.lower
 | 
| 583 |  | -        maxsize = data.upper - data.lower
 | 
| 584 |  | -        filesize = os.path.getsize(filename)
 | 
| 585 |  | -        if filesize > maxsize:
 | 
| 586 |  | -            raise ArgumentError("The file is too big, it doesn't fit into the user memory.")
 | 
| 587 |  | -        self.logger.info("Uploading application to "+self._hex(addr)+" - "+self._hex(addr+filesize)+"\n")
 | 
| 588 |  | -        self.embios.write(addr, f.read())
 | 
| 589 |  | -        self.execimage(addr)
 | 
|  | 553 | +        #self.execimage(addr) | 
|  | 554 | +        raise NotImplementedError | 
| 590 | 555 |  | 
| 591 | 556 | @command | 
| 592 | 557 | def execimage(self, addr): | 
| — | — | @@ -595,10 +560,19 @@ | 
| 596 | 561 | addr = self._hexint(addr) | 
| 597 | 562 | self.logger.info("Starting emBIOS app at "+self._hex(addr)+"\n") | 
| 598 | 563 | self.embios.execimage(addr) | 
| 599 |  | -
 | 
|  | 564 | + | 
| 600 | 565 | @command | 
| 601 |  | -    def readrawbootflash(self, addr_flash, addr_mem, size):
 | 
|  | 566 | +    def flushcaches(self): | 
| 602 | 567 | """ | 
|  | 568 | +            Flushes the CPUs data and instruction caches. | 
|  | 569 | +        """ | 
|  | 570 | +        self.logger.info("Flushing CPU data and instruction caches...") | 
|  | 571 | +        self.embios.flushcaches() | 
|  | 572 | +        self.logger.info("done\n") | 
|  | 573 | + | 
|  | 574 | +    @command | 
|  | 575 | +    def readbootflash(self, addr_flash, addr_mem, size): | 
|  | 576 | +        """ | 
| 603 | 577 | Reads <size> bytes from bootflash to memory. | 
| 604 | 578 | <addr_bootflsh>: the address in bootflash to read from | 
| 605 | 579 | <addr_mem>: the address in memory to copy the data to | 
| — | — | @@ -609,9 +583,9 @@ | 
| 610 | 584 | self.logger.info("Dumping boot flash addresses "+self._hex(addr_flash)+" - "+ | 
| 611 | 585 | hex(addr_flash+size)+" to "+self._hex(addr_mem)+" - "+self._hex(addr_mem+size)+"\n") | 
| 612 | 586 | self.embios.bootflashread(addr_flash, addr_mem, size) | 
| 613 |  | -
 | 
|  | 587 | + | 
| 614 | 588 | @command | 
| 615 |  | -    def writerawbootflash(self, addr_flash, addr_mem, size, force=False):
 | 
|  | 589 | +    def writebootflash(self, addr_flash, addr_mem, size, force=False): | 
| 616 | 590 | """ | 
| 617 | 591 | Writes <size> bytes from memory to bootflash. | 
| 618 | 592 | ATTENTION: Don't call this unless you really know what you're doing! | 
| — | — | @@ -628,23 +602,32 @@ | 
| 629 | 603 | hex(addr_mem+size)+" to "+self._hex(addr_flash)+" - "+self._hex(addr_flash+size)+"\n") | 
| 630 | 604 | if force == False: | 
| 631 | 605 | self.logger.info("If this was not what you intended press Ctrl-C NOW") | 
| 632 |  | -            import time
 | 
| 633 |  | -            for i in range(5):
 | 
|  | 606 | +            for i in range(10): | 
| 634 | 607 | self.logger.info(".") | 
| 635 | 608 | time.sleep(1) | 
| 636 | 609 | self.logger.info("\n") | 
| 637 | 610 | self.embios.bootflashwrite(addr_flash, addr_mem, size) | 
| 638 |  | -
 | 
|  | 611 | + | 
| 639 | 612 | @command | 
| 640 |  | -    def flushcaches(self):
 | 
|  | 613 | +    def runfirmware(self, addr, filename): | 
| 641 | 614 | """ | 
| 642 |  | -            Flushes the CPUs data and instruction caches.
 | 
|  | 615 | +            Uploads the firmware in 'filename' to the beginning of the | 
|  | 616 | +            user memory and executes it | 
| 643 | 617 | """ | 
| 644 |  | -        self.logger.info("Flushing CPU data and instruction caches...")
 | 
| 645 |  | -        self.embios.flushcaches()
 | 
| 646 |  | -        self.logger.info("done\n")
 | 
|  | 618 | +        addr = self._hexint(addr) | 
|  | 619 | +        self.uploadfile(addr, filename) | 
|  | 620 | +        self.execfirmware(addr) | 
| 647 | 621 |  | 
| 648 | 622 | @command | 
|  | 623 | +    def execfirmware(self, addr): | 
|  | 624 | +        """ | 
|  | 625 | +            Executes the firmware at addr | 
|  | 626 | +        """ | 
|  | 627 | +        addr = self._hexint(addr) | 
|  | 628 | +        self.logger.info("Running firmware at "+self._hex(addr)+". Bye.") | 
|  | 629 | +        self.embios.execfirmware(addr) | 
|  | 630 | + | 
|  | 631 | +    @command | 
| 649 | 632 | def aesencrypt(self, addr, size, keyindex): | 
| 650 | 633 | """ | 
| 651 | 634 | Encrypts a buffer using a hardware key | 
| Index: embios/trunk/tools/libembiosdata.py | 
| — | — | @@ -1,3 +1,26 @@ | 
|  | 2 | +#!/usr/bin/env python | 
|  | 3 | +# | 
|  | 4 | +# | 
|  | 5 | +#    Copyright 2010 TheSeven, benedikt93, Farthen | 
|  | 6 | +# | 
|  | 7 | +# | 
|  | 8 | +#    This file is part of emBIOS. | 
|  | 9 | +# | 
|  | 10 | +#    emBIOS is free software: you can redistribute it and/or | 
|  | 11 | +#    modify it under the terms of the GNU General Public License as | 
|  | 12 | +#    published by the Free Software Foundation, either version 2 of the | 
|  | 13 | +#    License, or (at your option) any later version. | 
|  | 14 | +# | 
|  | 15 | +#    emBIOS is distributed in the hope that it will be useful, | 
|  | 16 | +#    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 17 | +#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
|  | 18 | +#    See the GNU General Public License for more details. | 
|  | 19 | +# | 
|  | 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/>. | 
|  | 22 | +# | 
|  | 23 | +# | 
|  | 24 | + | 
| 2 | 25 | thread_state = ( | 
| 3 | 26 | "THREAD_FREE", | 
| 4 | 27 | "THREAD_SUSPENDED", | 
| — | — | @@ -20,7 +43,7 @@ | 
| 21 | 44 | thread_type = ( | 
| 22 | 45 | "USER_THREAD", | 
| 23 | 46 | "OS_THREAD", | 
| 24 |  | -    "ORE_THREAD"
 | 
|  | 47 | +    "CORE_THREAD" | 
| 25 | 48 | ) | 
| 26 | 49 |  | 
| 27 | 50 | hwtypes = { | 
| Index: embios/trunk/tools/libembios.py | 
| — | — | @@ -67,8 +67,12 @@ | 
| 68 | 68 |  | 
| 69 | 69 |  | 
| 70 | 70 | class Embios(object): | 
|  | 71 | +    """ | 
|  | 72 | +        Class for all embios functions. | 
|  | 73 | +    """ | 
| 71 | 74 | def __init__(self): | 
| 72 |  | -        self.lib = Lib(self)
 | 
|  | 75 | +        self.lib = Lib() | 
|  | 76 | +        self.getpacketsizeinfo() | 
| 73 | 77 |  | 
| 74 | 78 | @staticmethod | 
| 75 | 79 | def _alignsplit(addr, size, blksize, align): | 
| — | — | @@ -121,9 +125,7 @@ | 
| 122 | 126 | from the device. This cares about too long packages | 
| 123 | 127 | and decides whether to use DMA or not. | 
| 124 | 128 | """ | 
| 125 |  | -        if not self.lib.connected:
 | 
| 126 |  | -            self.lib.connect()
 | 
| 127 |  | -        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - 0x10
 | 
|  | 129 | +        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize | 
| 128 | 130 | din_maxsize = self.lib.dev.packetsizelimit["din"] | 
| 129 | 131 | data = "" | 
| 130 | 132 | (headsize, bodysize, tailsize) = self._alignsplit(addr, size, cin_maxsize, 16) | 
| — | — | @@ -148,9 +150,7 @@ | 
| 149 | 151 | in the memory of the device. This cares about too long packages | 
| 150 | 152 | and decides whether to use DMA or not. | 
| 151 | 153 | """ | 
| 152 |  | -        if not self.lib.connected:
 | 
| 153 |  | -            self.lib.connect()
 | 
| 154 |  | -        cout_maxsize = self.lib.dev.packetsizelimit["cout"] - 0x10
 | 
|  | 154 | +        cout_maxsize = self.lib.dev.packetsizelimit["cout"] - self.lib.headersize | 
| 155 | 155 | dout_maxsize = self.lib.dev.packetsizelimit["dout"] | 
| 156 | 156 | (headsize, bodysize, tailsize) = self._alignsplit(addr, len(data), cout_maxsize, 16) | 
| 157 | 157 | offset = 0 | 
| — | — | @@ -203,7 +203,7 @@ | 
| 204 | 204 | """ Reads a zero terminated string from memory | 
| 205 | 205 | Reads only a maximum of 'maxlength' chars. | 
| 206 | 206 | """ | 
| 207 |  | -        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - 0x10
 | 
|  | 207 | +        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize | 
| 208 | 208 | string = "" | 
| 209 | 209 | while (len(string) < maxlength or maxlength < 0): | 
| 210 | 210 | data = self.readmem(addr, min(maxlength - len(string), cin_maxsize)) | 
| — | — | @@ -218,25 +218,61 @@ | 
| 219 | 219 |  | 
| 220 | 220 | def i2cread(self, index, slaveaddr, startaddr, size): | 
| 221 | 221 | """ Reads data from an i2c slave """ | 
|  | 222 | +        if size > 256 or size < 1: | 
|  | 223 | +            raise ValueError("Size must be a number between 1 and 256") | 
|  | 224 | +        if size == 256: | 
|  | 225 | +            size = 0 | 
|  | 226 | +        resp = self.lib.monitorcommand(struct.pack("IBBBBII", 8, index, slaveaddr, startaddr, size, 0, 0), "III%ds" % size, (None, None, None, "data")) | 
|  | 227 | +        return resp.data | 
| 222 | 228 |  | 
| 223 | 229 | def i2cwrite(self, index, slaveaddr, startaddr, data): | 
| 224 | 230 | """ Writes data to an i2c slave """ | 
|  | 231 | +        size = len(data) | 
|  | 232 | +        if size > 256 or size < 1: | 
|  | 233 | +            raise ValueError("Size must be a number between 1 and 256") | 
|  | 234 | +        if size == 256: | 
|  | 235 | +            size = 0 | 
|  | 236 | +        return self.lib.monitorcommand(struct.pack("IBBBBII%ds" % size, 9, index, slaveaddr, startaddr, size, 0, 0, data), "III" % size, (None, None, None)) | 
| 225 | 237 |  | 
| 226 |  | -    def usbcread(self, size):
 | 
| 227 |  | -        """ Reads data with size 'size' from the USB console """
 | 
|  | 238 | +    def usbcread(self): | 
|  | 239 | +        """ Reads one packet with the maximal cin size """ | 
|  | 240 | +        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize | 
|  | 241 | +        resp = self.lib.monitorcommand(struct.pack("IIII", 10, cin_maxsize, 0, 0), "III%ds" % cin_maxsize, ("validsize", "buffersize", "queuesize", "data")) | 
|  | 242 | +        resp.data = resp.data[:resp.validsize] | 
|  | 243 | +        resp.maxsize = cin_maxsize | 
|  | 244 | +        return resp | 
| 228 | 245 |  | 
| 229 | 246 | def usbcwrite(self, data): | 
| 230 | 247 | """ Writes data to the USB console """ | 
|  | 248 | +        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize | 
|  | 249 | +        size = len(data) | 
|  | 250 | +        while len(data) > 0: | 
|  | 251 | +            writesize = min(cin_maxsize, len(data)) | 
|  | 252 | +            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 11, writesize, 0, 0, data[:writesize]), "III", ("validsize", "buffersize", "freesize")) | 
|  | 253 | +            data = data[resp.validsize:] | 
|  | 254 | +        return size | 
| 231 | 255 |  | 
| 232 |  | -    def cread(self, size, bitmask):
 | 
| 233 |  | -        """ Reads data with the specified size from the device consoles
 | 
|  | 256 | +    def cread(self, bitmask=0x1): | 
|  | 257 | +        """ Reads one packet with the maximal cin size from the device consoles | 
| 234 | 258 | identified with the specified bitmask | 
| 235 | 259 | """ | 
|  | 260 | +        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize | 
|  | 261 | +        resp = self.lib.monitorcommand(struct.pack("IIII", 14, cin_maxsize, 0, 0), "III%ds" % cin_maxsize, ("size", None, None)) | 
|  | 262 | +        resp.data = resp.data[size:] | 
|  | 263 | +        resp.maxsize = cin_maxsize | 
|  | 264 | +        return resp | 
| 236 | 265 |  | 
| 237 |  | -    def cwrite(self, data):
 | 
|  | 266 | +    def cwrite(self, data, bitmask=0x1): | 
| 238 | 267 | """ Writes data to the device consoles | 
| 239 | 268 | identified with the specified bitmask. | 
| 240 | 269 | """ | 
|  | 270 | +        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize | 
|  | 271 | +        size = len(data) | 
|  | 272 | +        while len(data) > 0: | 
|  | 273 | +            writesize = min(cin_maxsize, len(data)) | 
|  | 274 | +            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 13, writesize, 0, 0, data[:writesize]), "III", (None, None, None)) | 
|  | 275 | +            data = data[writesize:] | 
|  | 276 | +        return size | 
| 241 | 277 |  | 
| 242 | 278 | def cflush(self, bitmask): | 
| 243 | 279 | """ Flushes the consoles specified with 'bitmask' """ | 
| — | — | @@ -244,7 +280,7 @@ | 
| 245 | 281 |  | 
| 246 | 282 | def getprocinfo(self): | 
| 247 | 283 | """ Gets current state of the scheduler """ | 
| 248 |  | -        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - 0x10
 | 
|  | 284 | +        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize | 
| 249 | 285 | # Get the size | 
| 250 | 286 | schedulerstate = self.lockscheduler() | 
| 251 | 287 | resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "tablesize", None)) | 
| — | — | @@ -338,15 +374,15 @@ | 
| 339 | 375 | elif threadtype == "system": | 
| 340 | 376 | threadtype = 1 | 
| 341 | 377 | else: | 
| 342 |  | -            raise SyntaxError("Threadtype must be either 'system' or 'user'")
 | 
|  | 378 | +            raise ValueError("Threadtype must be either 'system' or 'user'") | 
| 343 | 379 | if priority > 256 or priority < 0: | 
| 344 |  | -            raise SyntaxError("Priority must be a number between 0 and 256")
 | 
|  | 380 | +            raise ValueError("Priority must be a number between 0 and 256") | 
| 345 | 381 | if state == "ready": | 
| 346 | 382 | state = 0 | 
| 347 | 383 | elif state == "suspended": | 
| 348 | 384 | state = 1 | 
| 349 | 385 | else: | 
| 350 |  | -            raise SyntaxError("State must be either 'ready' or 'suspended'")
 | 
|  | 386 | +            raise ValueError("State must be either 'ready' or 'suspended'") | 
| 351 | 387 | resp = self.lib.monitorcommand(struct.pack("IIIIIIII", 19, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state), "III", (id, None, None)) | 
| 352 | 388 | if resp.id < 0: | 
| 353 | 389 | raise DeviceError("The device returned the error code "+str(resp.id)) | 
| — | — | @@ -394,21 +430,19 @@ | 
| 395 | 431 |  | 
| 396 | 432 |  | 
| 397 | 433 | class Lib(object): | 
| 398 |  | -    def __init__(self, embios):
 | 
|  | 434 | +    def __init__(self): | 
| 399 | 435 | self.idVendor = 0xFFFF | 
| 400 | 436 | self.idProduct = 0xE000 | 
| 401 |  | -
 | 
| 402 |  | -        self.embios = embios
 | 
| 403 |  | -        self.connected = False
 | 
|  | 437 | + | 
|  | 438 | +        self.headersize = 0x10 | 
|  | 439 | + | 
|  | 440 | +        self.connect() | 
| 404 | 441 |  | 
| 405 | 442 | def connect(self): | 
| 406 | 443 | self.dev = Dev(self.idVendor, self.idProduct) | 
| 407 | 444 | self.connected = True | 
| 408 |  | -        self.embios.getpacketsizeinfo()
 | 
| 409 | 445 |  | 
| 410 | 446 | def monitorcommand(self, cmd, rcvdatatypes=None, rcvstruct=None): | 
| 411 |  | -        if not self.connected:
 | 
| 412 |  | -            self.connect()
 | 
| 413 | 447 | self.dev.cout(cmd) | 
| 414 | 448 | if rcvdatatypes: | 
| 415 | 449 | rcvdatatypes = "I" + rcvdatatypes # add the response | 
| — | — | @@ -441,7 +475,7 @@ | 
| 442 | 476 |  | 
| 443 | 477 | self.interface = 0 | 
| 444 | 478 | self.timeout = 100 | 
| 445 |  | -        
 | 
|  | 479 | + | 
| 446 | 480 | self.connect() | 
| 447 | 481 | self.findEndpoints() | 
| 448 | 482 |  | 
| — | — | @@ -484,13 +518,13 @@ | 
| 485 | 519 | def send(self, endpoint, data): | 
| 486 | 520 | size = self.dev.write(endpoint, data, self.interface, self.timeout) | 
| 487 | 521 | if size != len(data): | 
| 488 |  | -            raise SendError
 | 
|  | 522 | +            raise SendError("Not all data was written!") | 
| 489 | 523 | return len | 
| 490 | 524 |  | 
| 491 | 525 | def receive(self, endpoint, size): | 
| 492 | 526 | read = self.dev.read(endpoint, size, self.interface, self.timeout) | 
| 493 | 527 | if len(read) != size: | 
| 494 |  | -            raise ReceiveError
 | 
|  | 528 | +            raise ReceiveError("Requested size and read size don't match!") | 
| 495 | 529 | return read | 
| 496 | 530 |  | 
| 497 | 531 | def cout(self, data): |