# Path: bioloid/packet.py
# class Id:
# class Command:
# class ErrorCode:
# class Packet:
#     BROADCAST = 0xFE
#     INVALID = 0xFF
#     PING = 0x01         # Used to obatin a status packet
#     READ = 0x02         # Read values from the control table
#     WRITE = 0x03        # Write values to control table
#     REG_WRITE = 0x04    # Prime values to write when ACTION sent
#     ACTION = 0x05       # Triggers REG_WRITE
#     RESET = 0x06        # Changes control values back to factory defaults
#     SYNC_WRITE = 0x83   # Writes values to many devices
#     RESERVED = 0x80         # Reserved - set to zero
#     INSTRUCTION = 0x40      # Undefined instruction
#     OVERLOAD = 0x20         # Max torque can't control applied load
#     CHECKSUM = 0x10         # Checksum of instruction packet incorrect
#     RANGE = 0x08            # Instruction is out of range
#     OVERHEATING = 0x04      # Internal temperature is too high
#     ANGLE_LIMIT = 0x02      # Goal position is outside of limit range
#     INPUT_VOLTAGE = 0x01    # Input voltage out of range
#     NONE = 0x00             # No Error
#     NOT_DONE = 0x100        # Special error code used by packet::ProcessChar
#     TIMEOUT = 0x101         # Indicates that a timeout occurred while waiting
#     TOO_MUCH_DATA = 0x102   # Packet storage isn't big enough
#     def __init__(self, dev_id):
#     def __repr__(self):
#     def __str__(self):
#     def get_dev_id(self):
#     def __init__(self, cmd):
#     def __repr__(self):
#     def __str__(self):
#     def parse(string):
#     def __init__(self, error_code):
#     def __repr__(self):
#     def __str__(self):
#     def parse(error_str):
#     def __init__(self, status_packet=False):
#     def param_byte(self, idx):
#     def params(self):
#     def param_len(self):
#     def error_code(self):
#     def error_code_str(self):
#     def process_byte(self, byte):
# 
# Path: bioloid/dump_mem.py
# def dump_mem(buf, prefix='', addr=0, line_width=16, show_ascii=True,
#              show_addr=True, log=print):
#     """Dumps out a hex/ASCII representation of the given buffer."""
#     if line_width < 0:
#         line_width = 16
#     if len(prefix) > 0:
#         prefix += ':'
#     if buf is None or len(buf) == 0:
#         log(prefix + 'No data')
#         return
#     buf_len = len(buf)
#     # Use a memoryview to prevent unnecessary allocations
#     buf_mv = memoryview(buf)
#     line_ascii = ''
#     ascii_offset = 0
# 
#     prefix_bytes = bytes(prefix, 'utf-8')
#     prefix_len = len(prefix_bytes)
#     if prefix_len > 0:
#         prefix_len += 1     # For space between prefix and addr
#     max_len = prefix_len
#     if show_addr:
#         max_len += 6
#     hex_offset = max_len
#     max_len += line_width * 3 - 1
#     if show_ascii:
#         ascii_offset = max_len + 1
#         max_len += line_width + 1
#     out_line = memoryview(bytearray(max_len))
#     if prefix_len > 0:
#         out_line[0:prefix_len-1] = prefix_bytes
#         out_line[prefix_len-1:prefix_len] = b' '
# 
#     line_hex = out_line[hex_offset:hex_offset + (line_width * 3)]
#     if show_ascii:
#         # space between hex and ascii
#         out_line[ascii_offset-1:ascii_offset] = b' '
#         line_ascii = out_line[ascii_offset:ascii_offset + line_width]
# 
#     for offset in range(0, buf_len, line_width):
#         if show_addr:
#             out_line[prefix_len:prefix_len + 6] \
#                 = bytes('{:04x}: '.format(addr), 'ascii')
#         line_bytes = min(buf_len - offset, line_width)
#         line_hex[0:(line_bytes * 3)-1] \
#             = hexlify(buf_mv[offset:offset+line_bytes])
#         out_len = hex_offset + line_bytes * 3 - 1
#         if show_ascii:
#             if line_bytes < line_width:
#                 for i in range(line_bytes * 3 - 1, line_width * 3):
#                     line_hex[i:i+1] = b' '
#             line_ascii[0:line_bytes] = buf_mv[offset:offset + line_bytes]
#             for i in range(line_bytes):
#                 char = line_ascii[i]
#                 if char < 0x20 or char > 0x7e:
#                     line_ascii[i] = ord('.')
#             out_len = ascii_offset + line_bytes
#         log(bytes(out_line[0:out_len]).decode('utf-8'))
#         addr += line_width
# 
# Path: bioloid/log.py
# def log(*args):
#     """Make log call log_fn so that other modules can use:
# 
#        from log import log
# 
#        and then call log_to_xxx and have the changes take effect.
#     """
#     log_fn(args)


import pyb
from bioloid import packet
from bioloid.dump_mem import dump_mem
from bioloid.log import log
    def __init__(self, error_code, *args, **kwargs):
        super(BusError, self).__init__(self, *args, **kwargs)
        self.error_code = error_code

    def get_error_code(self):
        """Retrieves the error code associated with the exception."""
        return self.error_code

    def __str__(self):
        return "Rcvd Status: " + str(packet.ErrorCode(self.error_code))


class Bus:
    """The Bus class knows the commands used to talk to bioloid devices."""

    SHOW_NONE       = 0
    SHOW_COMMANDS   = (1 << 0)
    SHOW_PACKETS    = (1 << 1)

    def __init__(self, serial_port, show=SHOW_NONE):
        self.serial_port = serial_port
        self.show = show

    def action(self):
        """Broadcasts an action packet to all of the devices on the bus.
        This causes all of the devices to perform their deferred writes
        at the same time.

        """
        if self.show & Bus.SHOW_COMMANDS:

# Path: bioloid/packet.py
# class Id:
# class Command:
# class ErrorCode:
# class Packet:
#     BROADCAST = 0xFE
#     INVALID = 0xFF
#     PING = 0x01         # Used to obatin a status packet
#     READ = 0x02         # Read values from the control table
#     WRITE = 0x03        # Write values to control table
#     REG_WRITE = 0x04    # Prime values to write when ACTION sent
#     ACTION = 0x05       # Triggers REG_WRITE
#     RESET = 0x06        # Changes control values back to factory defaults
#     SYNC_WRITE = 0x83   # Writes values to many devices
#     RESERVED = 0x80         # Reserved - set to zero
#     INSTRUCTION = 0x40      # Undefined instruction
#     OVERLOAD = 0x20         # Max torque can't control applied load
#     CHECKSUM = 0x10         # Checksum of instruction packet incorrect
#     RANGE = 0x08            # Instruction is out of range
#     OVERHEATING = 0x04      # Internal temperature is too high
#     ANGLE_LIMIT = 0x02      # Goal position is outside of limit range
#     INPUT_VOLTAGE = 0x01    # Input voltage out of range
#     NONE = 0x00             # No Error
#     NOT_DONE = 0x100        # Special error code used by packet::ProcessChar
#     TIMEOUT = 0x101         # Indicates that a timeout occurred while waiting
#     TOO_MUCH_DATA = 0x102   # Packet storage isn't big enough
#     def __init__(self, dev_id):
#     def __repr__(self):
#     def __str__(self):
#     def get_dev_id(self):
#     def __init__(self, cmd):
#     def __repr__(self):
#     def __str__(self):
#     def parse(string):
#     def __init__(self, error_code):
#     def __repr__(self):
#     def __str__(self):
#     def parse(error_str):
#     def __init__(self, status_packet=False):
#     def param_byte(self, idx):
#     def params(self):
#     def param_len(self):
#     def error_code(self):
#     def error_code_str(self):
#     def process_byte(self, byte):
# 
# Path: bioloid/dump_mem.py
# def dump_mem(buf, prefix='', addr=0, line_width=16, show_ascii=True,
#              show_addr=True, log=print):
#     """Dumps out a hex/ASCII representation of the given buffer."""
#     if line_width < 0:
#         line_width = 16
#     if len(prefix) > 0:
#         prefix += ':'
#     if buf is None or len(buf) == 0:
#         log(prefix + 'No data')
#         return
#     buf_len = len(buf)
#     # Use a memoryview to prevent unnecessary allocations
#     buf_mv = memoryview(buf)
#     line_ascii = ''
#     ascii_offset = 0
# 
#     prefix_bytes = bytes(prefix, 'utf-8')
#     prefix_len = len(prefix_bytes)
#     if prefix_len > 0:
#         prefix_len += 1     # For space between prefix and addr
#     max_len = prefix_len
#     if show_addr:
#         max_len += 6
#     hex_offset = max_len
#     max_len += line_width * 3 - 1
#     if show_ascii:
#         ascii_offset = max_len + 1
#         max_len += line_width + 1
#     out_line = memoryview(bytearray(max_len))
#     if prefix_len > 0:
#         out_line[0:prefix_len-1] = prefix_bytes
#         out_line[prefix_len-1:prefix_len] = b' '
# 
#     line_hex = out_line[hex_offset:hex_offset + (line_width * 3)]
#     if show_ascii:
#         # space between hex and ascii
#         out_line[ascii_offset-1:ascii_offset] = b' '
#         line_ascii = out_line[ascii_offset:ascii_offset + line_width]
# 
#     for offset in range(0, buf_len, line_width):
#         if show_addr:
#             out_line[prefix_len:prefix_len + 6] \
#                 = bytes('{:04x}: '.format(addr), 'ascii')
#         line_bytes = min(buf_len - offset, line_width)
#         line_hex[0:(line_bytes * 3)-1] \
#             = hexlify(buf_mv[offset:offset+line_bytes])
#         out_len = hex_offset + line_bytes * 3 - 1
#         if show_ascii:
#             if line_bytes < line_width:
#                 for i in range(line_bytes * 3 - 1, line_width * 3):
#                     line_hex[i:i+1] = b' '
#             line_ascii[0:line_bytes] = buf_mv[offset:offset + line_bytes]
#             for i in range(line_bytes):
#                 char = line_ascii[i]
#                 if char < 0x20 or char > 0x7e:
#                     line_ascii[i] = ord('.')
#             out_len = ascii_offset + line_bytes
#         log(bytes(out_line[0:out_len]).decode('utf-8'))
#         addr += line_width
# 
# Path: bioloid/log.py
# def log(*args):
#     """Make log call log_fn so that other modules can use:
# 
#        from log import log
# 
#        and then call log_to_xxx and have the changes take effect.
#     """
#     log_fn(args)


# Path: bioloid/bus.py
import pyb
from bioloid import packet
from bioloid.dump_mem import dump_mem
from bioloid.log import log

    def __init__(self, error_code, *args, **kwargs):
        super(BusError, self).__init__(self, *args, **kwargs)
        self.error_code = error_code

    def get_error_code(self):
        """Retrieves the error code associated with the exception."""
        return self.error_code

    def __str__(self):
        return "Rcvd Status: " + str(packet.ErrorCode(self.error_code))


class Bus:
    """The Bus class knows the commands used to talk to bioloid devices."""

    SHOW_NONE       = 0
    SHOW_COMMANDS   = (1 << 0)
    SHOW_PACKETS    = (1 << 1)

    def __init__(self, serial_port, show=SHOW_NONE):
        self.serial_port = serial_port
        self.show = show

    def action(self):
        """Broadcasts an action packet to all of the devices on the bus.
        This causes all of the devices to perform their deferred writes
        at the same time.

        """
        if self.show & Bus.SHOW_COMMANDS:

            log('Broadcasting ACTION')