Ejemplo n.º 1
0
    def reset(self):
        if self.dev != None:
            del self.dev
            self.dev = None

        self.dev = Device(self.device_id,
                          auto_detach=(platform.system() != "Windows"))
        self.setup()
Ejemplo n.º 2
0
class SerialDisplay:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.codebook = SerialDisplay.create_codebook()

        self.xcors = []
        self.ycors = []
        self.pcors = []

        for y in range(height):
            for x in range(width):
                for p in range(8):
                    self.xcors.append(x if not (y & 1) else (width - 1 - x))
                    self.ycors.append(y)
                    self.pcors.append(p)


        self.dev = Device()
        self.dev.baudrate = 3010000
        self.dev.ftdi_fn.ftdi_set_line_property(7, 0, 0)

    def display(self, image):
        data = np.zeros([self.width * self.height * 8], dtype=np.uint8)
        data[:] = 0xFF
        image = np.array(np.clip(image * 255, 0, 255), dtype=np.uint8)

        for c in range(3):
            data &= self.codebook[c, image[self.xcors, self.ycors, c], self.pcors]

        self.dev.write(bytes(data.data))

    @staticmethod
    def format_byte(b0, b1, b2):
        return [(not b0) | (1 << 1) | ((not b1) << 3) | (1 << 4) | ((not b2) << 6)]

    @staticmethod
    def format_color(r, g, b):
        color = ((g & 0xFF) << 16) | ((r & 0xFF) << 8) | (b & 0xFF)

        result = []
        for i in range(8):
            trip = (color >> (24 - 3 * (i + 1))) & 7
            result += SerialDisplay.format_byte(trip & 4, trip & 2, trip & 1)
        return bytes(result)

    @staticmethod
    def create_codebook():
        codebook = np.zeros([3, 256, 8], dtype=np.uint8)
        for c in range(3):
            for p in range(8):
                for v in range(256):
                    m = [0, 0, 0]
                    m[c] = v
                    codebook[c, v, p] = SerialDisplay.format_color(*m)[p]
        return codebook
    def connect(self):
        self.target = Device(device_id=self.dev_id, interface_select=1)
        self.target.flush()
        time.sleep(0.01)

        BITMODE_SYNCFF = 0x40
        SIO_RTS_CTS_HS = (0x1 << 8)
        self.target.ftdi_fn.ftdi_set_bitmode(0, BITMODE_SYNCFF)
        self.target.ftdi_fn.ftdi_setflowctrl(SIO_RTS_CTS_HS)
        self.target.flush()
Ejemplo n.º 4
0
 def __init__(self, device_index=0):
     """Initialise the driver."""
     try:
         Device.__init__(self, mode="b", device_index=device_index)
     except LibraryMissingError:
         raise Exception(
             "Dependency libftdi not found. Check the README for driver dependencies."
         )
     self.baudrate = 250000
     self.ftdi_fn.ftdi_set_line_property(FT232R._BITS_8,
                                         FT232R._STOP_BITS_2,
                                         FT232R._PARITY_NONE)
Ejemplo n.º 5
0
  def _ftdisend(self, data, mode):
    data_parity = self._parityOf(int(hexlify(data), 16))

    if data_parity == -1:
      if mode:
        #parity = serial.PARITY_EVEN
        parity = 2
      else:
        #parity = serial.PARITY_ODD
        parity = 1
    else:
      if mode:
        #parity = serial.PARITY_ODD
        parity = 1
      else:
        #parity = serial.PARITY_EVEN
        parity = 2
    try:
        self.__device = Device(self.__deviceid)
        self.__device.ftdi_fn.ftdi_set_line_property(8, 1, parity)
        self.__device.baudrate = 9600
        self.__device.write(data)
        self.__device.flush()
    except pylibftdi.FtdiError:
        print "FtdiError"
        self._ftdisend(data, mode)
Ejemplo n.º 6
0
 def write(self, data: List[int]):
     """Write 512 bytes or less of DMX data."""
     try:
         byte_data = bytes(data)
     except TypeError:
         byte_data = self.encoder.encode(data)
     # Break
     self._set_break_on()
     wait_ms(10)
     # Mark after break
     self._set_break_off()
     wait_us(8)
     # Frame body
     Device.write(self, b"\x00" + byte_data)
     # Idle
     wait_ms(15)
Ejemplo n.º 7
0
    def __init__(self, port, baud=115200):
        """
        Initializes SCPI slave device from a given port.

        Port can either be an already initialized pyserial port
        or may be a string, specifiying the port to be used.
        Special name: hamegusb, this uses the HM2008 USB interface
        """
        if ( type(port) is str):
            if (port == "hamegusb"):
                USB_PID_LIST.append(0xED72);
                self.__ser = Device(mode='b')
            else:
        # configure the serial connections (the parameters differs from device
        # to device you are connecting to)
                self.__ser = serial.Serial(
                   port=port,
                   baudrate=baud,
                   parity=serial.PARITY_NONE,
                   stopbits=serial.STOPBITS_ONE,
                   bytesize=serial.EIGHTBITS
                )
        else:
            self.__ser = port
        # Try at least an *IDN? command, if this fails
        # most likely nothing will work on the device at all.
        self.__device_id = self.query_string("*IDN?", 1);
        print "Found >>"+self.__device_id
Ejemplo n.º 8
0
	def __init__(self, int_select):
		self.dev = Device(mode='b', interface_select = int_select, auto_detach=False, device_id = 'Dual RS232-HS' )

		self.write_port_l = 0x80
		self.read_port_l = 0x81
		self.write_port_h = 0x82
		self.read_port_h = 0x83
		self.port_l = port(self.dev,self.write_port_l, self.read_port_l)
		self.port_h = port(self.dev,self.write_port_h, self.read_port_h)	
Ejemplo n.º 9
0
    def __init__(self, queue):
        """Initialize the communication worker"""

        # call constructor of super class
        threading.Thread.__init__(self)

        # set queue
        self.queue = queue

        # set FTDI device for communication with iCEstick
        try:
            self.dev = Device(mode='b', interface_select=INTERFACE_B)

            # set baudrate
            self.dev.baudrate = self.BAUD_RATE
        except:
            global exit_flag
            print(fg.li_red +
                  "[-] Could not connect to FTDI serial interface" + fg.rs)
            exit(1)
Ejemplo n.º 10
0
 def __init__(self,deviceId=""):
     '''
     Constructor
     '''
     self._ID = None
     self._HWID = None
     self._Cluster = None
     
     self._firstCmd = True
     self._errorFlag = False
     self._errorMSg = ""
     self._stick = None
     if deviceId == "":
         log_trace('C', '0067', "No deviceID provided", traceback=traceback.print_stack())
         pass #self.stick = Device(mode = "t")
     else:
         try:
             self._stick = Device(device_id=deviceId,mode = "t")
             self._stick.open()
             #one call of the baudrate setter does not always work 
             self._stick.baudrate = 3000000
         except:
             log_trace('E', '0068', "Error when opening new device", ID=deviceId, exception=', '.join(sys.exc_info()[0]))
             if self._stick:
                 self._stick.close()
             self._stick = None
             #ERR408
             return
         self._HWID = deviceId
         self._ID = self.GETID()
         if self._ID:
             self._ID = self._ID.split()[0]
         else:
             log_trace('E', '0069', "GETID() returned no data", HWID=deviceId)
             self._stick.close()
             self._stick = None
             # ERR405
             return
             
         self._Cluster = self.GETCLUSTER()
         if self._Cluster:
             self._Cluster = self._Cluster.split()[0]
         else:
             log_trace('E', '0070', "GETCLUSTER() returned no data", HWID=deviceId)
             self._stick.close()
             self._stick = None
             #ERR406
             return
         
         if (self._ID[:3]=="ERR") or (self._Cluster[:3]=="ERR"):
             log_trace('E', '0071', "Device initialisation returned an error (GETID or GETCLUSTER)", HWID=deviceId, ID=self._ID, cluster=self._Cluster)
             self._stick.close()
             self._stick = None
Ejemplo n.º 11
0
class LoopbackTester(object):
    def __init__(self):
        self.device = Device()

    def test_loopback(self, lengths):
        self.device.flush()
        time.sleep(0.1)
        for l in lengths:
            test_str = test_string(l)
            if self.device.write(test_str) != len(test_str):
                sys.stdout.write('*')
            time.sleep(0.1)
            result = ''
            for _ in range(3):
                result = self.device.read(l)
                if result:
                    break
            if result != test_str:
                self.device.flush()
                time.sleep(0.25)
            yield result == test_str

    def main(self):
        for bd in [9600, 31250, 115200, 1152000]:
            self.device.baudrate = bd

            for result in self.test_loopback(range(1, 50) + range(100, 500, 100) +
                                             range(1000, 5000, 1000)):
                if result:
                    sys.stdout.write('+')
                else:
                    sys.stdout.write('!')
            sys.stdout.write('\n')
Ejemplo n.º 12
0
def compute(threadname):
    """ Compute the force """
    dev = Device()
    dev.baudrate = 230400
    lastupdate = pg.ptime.time()
    i = 0
    while True:
        taille = HAPTICDEV.incommingsize() #FIFO.qsize()
        if taille >= 3:
            rec = HAPTICDEV.readarray(3)#bytearray(extract(FIFO, 3))
            taille = taille - 3
            if rec[0] != 5:
                while rec[0] != 5:
                    rec = HAPTICDEV.readarray(1)#bytearray(extract(FIFO, 1))
                    taille = taille - 1
                rec[1:2] = HAPTICDEV.readarray(2)#bytearray(extract(FIFO, 2))
                taille = taille - 2
            if rec[0] == 5:
                i += 1
                angle = rec[1] + rec[2] * 256
                if angle > 32767:
                    angle -= 65536
                degre = angle*360/20000
                data = SHARED['data']
                data[:-1] = data[1:]
                data[-1] = degre
                SHARED['data'] = data
                indexf = max(min(int((ANGLEMAX+degre)*RESANG), ANGLEMAX*RESANG*2-1), 0)
                forcenow = FORCE[indexf]
                forcenow = max(min(forcenow, 130), -130)
                HAPTICDEV.write(forcenow)
                SHARED['degre'] = degre
                SHARED['forcenow'] = forcenow

                if i >= COUNT:
                    i = 0
                    now = pg.ptime.time()
                    SHARED['fps'] = COUNT / (now - lastupdate)
                    SHARED['taille'] = taille
                    lastupdate = now
Ejemplo n.º 13
0
class LoopbackTester(object):
    def __init__(self):
        self.device = Device()

    def test_loopback(self, lengths):
        self.device.flush()
        time.sleep(0.1)
        for l in lengths:
            test_str = test_string(l)
            if self.device.write(test_str) != len(test_str):
                sys.stdout.write('*')
            time.sleep(0.1)
            result = ''
            for _ in range(3):
                result = self.device.read(l)
                if result:
                    break
            if result != test_str:
                self.device.flush()
                time.sleep(0.25)
            yield result == test_str

    def main(self):
        for bd in [9600, 31250, 115200, 1152000]:
            self.device.baudrate = bd

            for result in self.test_loopback(
                    range(1, 50) + range(100, 500, 100) +
                    range(1000, 5000, 1000)):
                if result:
                    sys.stdout.write('+')
                else:
                    sys.stdout.write('!')
            sys.stdout.write('\n')
Ejemplo n.º 14
0
class RS485Monitor(object):
    __metaclass__ = abc.ABCMeta

    def __init__(self, a, mode='t', baudrate=1250000,
                 databits=8, stopbits=0, paritymode=2):
        self._single = a.single
        self._count = 0
        self._out = UnbufferedStreamWrapper(stdout)

        try:
            self._d = Device()
            self._d.baudrate = baudrate
            self._d.ftdi_fn.ftdi_set_line_property(databits,
                                                   stopbits,
                                                   paritymode)
            self._d.flush()
        except FtdiError as e:
            self._d = None
            raise FtdiError('could not start FTDI Device "' + e.args[0] + '"')

    def __del__(self):
        try:
            if self._d:
                self._d.flush()
                self._d.close()
        except:
            print 'Destroy failed'
        print normColor + '\nExiting monitor'

    @abc.abstractmethod
    def run(self):
        pass
Ejemplo n.º 15
0
Archivo: arm.py Proyecto: dwiel/ssc_32u
    def __init__(self, fps, velocity_scale=200, dry_run=False, verbose=False):
        """
        fps: the frames per second that set_multi_velocity must be called to
        keep smooth motion.
        velocity_scale: convert unitless range (-1, 1) to velocity in
        microseconds / second
        """
        if not dry_run:
            self.dev = Device(mode='t')
            self.dev.baudrate = 9600

        self.default_speed = 600
        self.positions = self._home_position()

        self.fps = fps
        self.velocity_scale = velocity_scale

        # position scale is the velocity in (microseconds / second) / FPS to get
        # microseconds per frame
        self.position_scale = velocity_scale / self.fps

        self.dry_run = dry_run
        self.verbose = verbose
Ejemplo n.º 16
0
    def __init__(self,
                 start_offset=0,
                 end_offset=5000,
                 offset_step=1,
                 duration_step=1,
                 start_duration=1,
                 end_duration=30,
                 retries=2):
        """Initialize the glitcher"""

        # set FTDI device for communication with iCEstick
        self.dev = Device(mode='b', interface_select=INTERFACE_B)

        # set baudrate
        self.dev.baudrate = 115200

        # set offset and duration steps
        self.offset_step = offset_step
        self.duration_step = duration_step
        self.start_offset = start_offset
        self.end_offset = end_offset
        self.start_duration = start_duration
        self.end_duration = end_duration
        self.retries = retries
Ejemplo n.º 17
0
    def __init__(self, a, mode='t', baudrate=1250000,
                 databits=8, stopbits=0, paritymode=2):
        self._single = a.single
        self._count = 0
        self._out = UnbufferedStreamWrapper(stdout)

        try:
            self._d = Device()
            self._d.baudrate = baudrate
            self._d.ftdi_fn.ftdi_set_line_property(databits,
                                                   stopbits,
                                                   paritymode)
            self._d.flush()
        except FtdiError as e:
            self._d = None
            raise FtdiError('could not start FTDI Device "' + e.args[0] + '"')
Ejemplo n.º 18
0
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.codebook = SerialDisplay.create_codebook()

        self.xcors = []
        self.ycors = []
        self.pcors = []

        for y in range(height):
            for x in range(width):
                for p in range(8):
                    self.xcors.append(x if not (y & 1) else (width - 1 - x))
                    self.ycors.append(y)
                    self.pcors.append(p)


        self.dev = Device()
        self.dev.baudrate = 3010000
        self.dev.ftdi_fn.ftdi_set_line_property(7, 0, 0)
Ejemplo n.º 19
0
    def _connect(self):
        try:
            # Attempt to construct an FTDI Device
            self._dev = Device('MON001')

            # Reset the mode, then switch into serial FIFO
            self._dev.ftdi_fn.ftdi_set_bitmode(0xFF, 0x00)
            time.sleep(0.01)
            self._dev.ftdi_fn.ftdi_set_bitmode(0xFF, 0x40)

            # Set communication params
            self._dev.ftdi_fn.ftdi_set_latency_timer(5)
            self._dev.ftdi_fn.ftdi_setflowctrl(0)
            self._dev.ftdi_fn.ftdi_usb_purge_buffers()

            # Mark ourselves connected
            self.connected.emit(True)

        except FtdiError:
            pass
Ejemplo n.º 20
0
 def __init__(
     self,
     name: str,
     device_id: str,
     sensor: common.sensor.BaseSensor,
     callback_func: Callable,
     log: logging.Logger,
 ) -> None:
     super().__init__(
         name=name,
         device_id=device_id,
         sensor=sensor,
         callback_func=callback_func,
         log=log,
     )
     self.vcp: Device = Device(
         self.device_id,
         mode="t",
         encoding="ASCII",
         lazy_open=True,
         auto_detach=False,
     )
Ejemplo n.º 21
0
class CommunicationThread(threading.Thread):
    """Thread for fast serial communication"""

    BAUD_RATE = 2000000  # baud rate for serial communication
    BUFFER_SIZE = 64  # read buffer size in bytes

    def __init__(self, queue):
        """Initialize the communication worker"""

        # call constructor of super class
        threading.Thread.__init__(self)

        # set queue
        self.queue = queue

        # set FTDI device for communication with iCEstick
        try:
            self.dev = Device(mode='b', interface_select=INTERFACE_B)

            # set baudrate
            self.dev.baudrate = self.BAUD_RATE
        except:
            global exit_flag
            print(fg.li_red +
                  "[-] Could not connect to FTDI serial interface" + fg.rs)
            exit(1)

    def run(self):
        """Receive data"""
        global exit_flag

        while not exit_flag:
            if not self.queue.full():
                item = self.dev.read(self.BUFFER_SIZE)
                if item != b'':
                    self.queue.put(item)
Ejemplo n.º 22
0
class HondaECU(object):
    def __init__(self, device_id=None, latency=None, baudrate=10400):
        super(HondaECU, self).__init__()
        self.device_id = device_id
        self.dev = None
        self.error = 0
        self.resets = 0
        self.latency = latency
        self.baudrate = baudrate
        self.reset()

    def reset(self):
        if self.dev != None:
            del self.dev
            self.dev = None

        self.dev = Device(self.device_id,
                          auto_detach=(platform.system() != "Windows"))
        self.setup()

    def setup(self):
        self.dev.ftdi_fn.ftdi_usb_reset()
        self.dev.ftdi_fn.ftdi_usb_purge_buffers()
        self.dev.ftdi_fn.ftdi_set_line_property(8, 1, 0)
        self.dev.baudrate = self.baudrate
        if self.latency:
            self.dev.ftdi_fn.ftdi_set_latency_timer(self.latency)
        latency = c_ubyte()
        self.dev.ftdi_fn.ftdi_get_latency_timer(byref(latency))

    def _break(self, ms):
        self.dev.ftdi_fn.ftdi_set_bitmode(1, 0x01)
        self.dev._write(b'\x00')
        time.sleep(ms)
        self.dev._write(b'\x01')
        self.dev.ftdi_fn.ftdi_set_bitmode(0, 0x00)
        self.dev.flush()

    def wakeup(self):
        self._break(.070)
        time.sleep(.130)

    def ping(self):
        return self.send_command([0xfe], [0x72], retries=0) != None

    def probe_tables(self, tables=None):
        if not tables:
            tables = [
                0x10, 0x11, 0x17, 0x20, 0x21, 0x60, 0x61, 0x67, 0x70, 0x71,
                0xd0, 0xd1
            ]
        ret = {}
        for t in tables:
            info = self.send_command([0x72], [0x71, t])
            if info:
                if info[3] > 2:
                    ret[t] = [info[3], info[2]]
            else:
                return {}
        return ret

    def init(self):
        self.wakeup()
        return self.ping()

    def kline_new(self):
        pin_byte = c_ubyte()
        self.dev.ftdi_fn.ftdi_read_pins(byref(pin_byte))
        return (pin_byte.value == 0xff)

    def kline(self, timeout=.05):
        self.dev.flush()
        self.dev._write(b"\x00")
        to = time.time()
        while time.time() - to < timeout:
            tmp = self.dev._read(1)
            if len(tmp) == 1:
                return tmp == b"\x00"
        return False

    def kline_alt(self):
        self.dev.flush()
        self.dev._write(b"\xff")
        return self.dev._read(1) == b"\xff"

    def kline_old(self):
        b = create_string_buffer(2)
        self.dev.ftdi_fn.ftdi_poll_modem_status(b)
        return b.raw[1] & 16 == 0

    def send(self, buf, ml, timeout=.001):
        self.dev.flush()
        msg = "".join([chr(b) for b in buf]).encode("latin1")
        self.dev._write(msg)
        r = len(msg)
        timeout = .05 + timeout * r
        to = time.time()
        while r > 0:
            r -= len(self.dev._read(r))
            if time.time() - to > timeout: return None
        buf = bytearray()
        r = ml + 1
        while r > 0:
            tmp = self.dev._read(r)
            r -= len(tmp)
            buf.extend(tmp)
            if time.time() - to > timeout: return None
        r = buf[-1] - ml - 1
        while r > 0:
            tmp = self.dev._read(r)
            r -= len(tmp)
            buf.extend(tmp)
            if time.time() - to > timeout: return None
        return buf

    def send_command(self, mtype, data=[], retries=1):
        msg, ml, dl = format_message(mtype, data)
        r = 0
        while r <= retries:
            dispatcher.send(signal="ecu.debug",
                            sender=self,
                            msg="%d > [%s]" %
                            (r, ", ".join(["%02x" % m for m in msg])))
            resp = self.send(msg, ml)
            if resp:
                if checksum8bitHonda(resp[:-1]) == resp[-1]:
                    dispatcher.send(signal="ecu.debug",
                                    sender=self,
                                    msg="%d < [%s]" %
                                    (r, ", ".join(["%02x" % r for r in resp])))
                    rmtype = resp[:ml]
                    valid = False
                    if ml == 3:
                        valid = (rmtype[:2] == bytearray(
                            map(lambda x: x | 0x10, mtype[:2])))
                    elif ml == 1:
                        valid = (rmtype == bytearray(
                            map(lambda x: x & 0xf, mtype)))
                    if valid:
                        rml = resp[ml:(ml + 1)]
                        rdl = ord(rml) - 2 - len(rmtype)
                        rdata = resp[(ml + 1):-1]
                        return (rmtype, rml, rdata, rdl)
                    else:
                        return None
            r += 1

    def detect_ecu_state_new(self):
        t0 = self.send_command([0x72], [0x71, 0x00], retries=0)
        if t0 is None:
            self.wakeup()
            self.ping()
            t0 = self.send_command([0x72], [0x71, 0x00], retries=0)
        if not t0 is None:
            if bytes(t0[2][5:7]) != b"\x00\x00":
                return ECUSTATE.OK
            else:
                if self.send_command([0x7d], [0x01, 0x01, 0x00], retries=0):
                    return ECUSTATE.RECOVER_OLD
                if self.send_command([0x7b], [0x00, 0x01, 0x01], retries=0):
                    return ECUSTATE.RECOVER_NEW
        else:
            writestatus = self.send_command([0x7e], [0x01, 0x01, 0x00],
                                            retries=0)
            if not writestatus is None:
                if writestatus[2][1] == 0x0f:
                    return ECUSTATE.WRITE_GOOD
                elif writestatus[2][1] == 0x10:
                    return ECUSTATE.WRITE_INIT_OLD
                elif writestatus[2][1] == 0x20:
                    return ECUSTATE.WRITE_INIT_NEW
                elif writestatus[2][1] == 0x30:
                    return ECUSTATE.ERASE
                elif writestatus[2][1] == 0x40:
                    return ECUSTATE.WRITE
                elif writestatus[2][1] == 0x0:
                    return ECUSTATE.WRITE_UNKNOWN1
                else:
                    return ECUSTATE.ERROR
            else:
                readinfo = self.send_command([0x82, 0x82, 0x00],
                                             [0x00, 0x00, 0x00, 0x08],
                                             retries=0)
                if not readinfo is None:
                    return ECUSTATE.READ
        return ECUSTATE.OFF if not self.kline() else ECUSTATE.UNKNOWN

    def do_init_recover(self):
        self.send_command([0x7b], [0x00, 0x01, 0x01])
        self.send_command([0x7b], [0x00, 0x01, 0x02])
        self.send_command([0x7b], [0x00, 0x01, 0x03])
        self.send_command([0x7b], [0x00, 0x02, 0x76, 0x03, 0x17])
        self.send_command([0x7b], [0x00, 0x03, 0x75, 0x05, 0x13])

    def do_init_write(self):
        self.send_command([0x7d], [0x01, 0x01, 0x01])
        self.send_command([0x7d], [0x01, 0x01, 0x02])
        self.send_command([0x7d], [0x01, 0x01, 0x03])
        self.send_command([0x7d], [0x01, 0x02, 0x50, 0x47, 0x4d])
        self.send_command([0x7d], [0x01, 0x03, 0x2d, 0x46, 0x49])

    def do_erase(self):
        self.send_command([0x7e], [0x01, 0x02])
        self.send_command([0x7e], [0x01, 0x03, 0x00, 0x00])
        self.send_command([0x7e],
                          [0x01, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff])
        self.send_command([0x7e], [0x01, 0x0e, 0x01, 0x90])
        self.send_command([0x7e], [0x01, 0x01, 0x01])
        self.send_command([0x7e], [0x01, 0x04, 0xff])

    def do_erase_wait(self):
        cont = 1
        while cont:
            info = self.send_command([0x7e], [0x01, 0x05])
            if info:
                if info[2][1] == 0x00:
                    cont = 0
            else:
                cont = -1
        if cont == 0:
            into = self.send_command([0x7e], [0x01, 0x01, 0x00])

    def do_post_write(self):
        self.send_command([0x7e], [0x01, 0x09])
        time.sleep(.5)
        self.send_command([0x7e], [0x01, 0x0a])
        time.sleep(.5)
        self.send_command([0x7e], [0x01, 0x0c])
        time.sleep(.5)
        info = self.send_command([0x7e], [0x01, 0x0d])
        if info: return (info[2][1] == 0x0f)

    def get_faults(self):
        faults = {'past': [], 'current': []}
        for i in range(1, 0x0c):
            info_current = self.send_command([0x72], [0x74, i])[2]
            for j in [3, 5, 7]:
                if info_current[j] != 0:
                    faults['current'].append(
                        "%02d-%02d" % (info_current[j], info_current[j + 1]))
            if info_current[2] == 0:
                break
        for i in range(1, 0x0c):
            info_past = self.send_command([0x72], [0x73, i])[2]
            for j in [3, 5, 7]:
                if info_past[j] != 0:
                    faults['past'].append("%02d-%02d" %
                                          (info_past[j], info_past[j + 1]))
            if info_past[2] == 0:
                break
        return faults
Ejemplo n.º 23
0
Archivo: arm.py Proyecto: dwiel/ssc_32u
class Arm(object):
    def __init__(self, fps, velocity_scale=200, dry_run=False, verbose=False):
        """
        fps: the frames per second that set_multi_velocity must be called to
        keep smooth motion.
        velocity_scale: convert unitless range (-1, 1) to velocity in
        microseconds / second
        """
        if not dry_run:
            self.dev = Device(mode='t')
            self.dev.baudrate = 9600

        self.default_speed = 600
        self.positions = self._home_position()

        self.fps = fps
        self.velocity_scale = velocity_scale

        # position scale is the velocity in (microseconds / second) / FPS to get
        # microseconds per frame
        self.position_scale = velocity_scale / self.fps

        self.dry_run = dry_run
        self.verbose = verbose

    def _home_position(self):
        return {i: BOUNDS[i][2] for i in BOUNDS}

    def _bound_position(self, axis, position):
        if position > BOUNDS[axis][1]:
            return BOUNDS[axis][1]
        if position < BOUNDS[axis][0]:
            return BOUNDS[axis][0]
        return position

    def set_position(self, axis, position, speed=None, time=None):
        """
        pos: position pulse width in microseconds
        speed: microseconds per second
        time: time in milliseconds to execute motion to `pos`
        """

        self.positions[axis] = self._bound_position(axis, position)

        if speed is None and time is None:
            speed = self.default_speed

        if self.verbose:
            print('axis=', axis)
            print('position=', position)
            print('speed=', speed)
            print('time=', time)

        if self.dry_run:
            return

        if speed:
            self.dev.write(
                '#{axis}P{position}S{speed}\r'.format(
                    axis=axis, position=position, speed=speed
                )
            )
        else:
            self.dev.write(
                '#{axis}P{position}T{time}\r'.format(
                    axis=axis, position=position, time=time
                )
            )

    def set_positions(self, positions, speeds=None, scaled=False):
        if scaled:
            positions = {
                axis: self._scaled_to_absoltuion_position(axis, position)
                for axis, position in positions.items()
            }

        for axis in positions:
            positions[axis] = self._bound_position(axis, positions[axis])
            self.positions[axis] = positions[axis]

        if speeds is None:
            speeds = {axis: self.default_speed for axis in positions}

        if self.verbose:
            print('positions', positions)
            print('speeds   ', speeds)

        if self.dry_run:
            return

        self.dev.write(
            ''.join(
                '#{axis}P{pos}S{speed}'.format(
                    axis=axis,
                    pos=positions[axis],
                    speed=speeds[axis],
                ) for axis in positions
            ) + '\r'
        )

    def _scaled_position(self, axis, position):
        return (position - BOUNDS[axis][0]) / (
            BOUNDS[axis][1] - BOUNDS[axis][0]
        )

    def scaled_positions(self):
        return [
            self._scaled_position(axis, position)
            for axis, position in self.positions.items()
        ]

    def _scaled_to_absoltuion_position(self, axis, position):
        if position < 0 or position > 1:
            raise ValueError((
                'position expected to be within 0 and 1.  found: {}'
            ).format(position))

        return BOUNDS[axis][0] + position * (BOUNDS[axis][1] - BOUNDS[axis][0])

    def set_scaled_position(self, axis, position, speed=None):
        self.set_position(
            axis,
            self._scaled_to_absoltuion_position(axis, position),
            speed=speed
        )

    def set_relative_position(self, axis, position_delta, speed=None):
        self.positions[axis] += position_delta
        self.set_position(axis, self.positions[axis], speed=speed)

    def set_velocities(self, velocities):
        """
        Set velocity of all servos in arm.

        set_multi_velocity must be called once every self.fps
        """
        if set(velocities.keys()) != set(self.positions.keys()):
            raise ValueError((
                'velocities.keys must match self.positions.keys:\n'
                '  velocities.keys(): {}\n'
                '  self.position.keys(): {}\n'
            ).format(velocities.keys(), self.positions.keys()))

        if not any(v != 0 for v in velocities.values()):
            return

        self.set_positions(
            {
                axis: self.positions[axis] + (velocity * self.position_scale)
                for axis, velocity in velocities.items()
            },
            {
                axis: max(abs(velocity * self.velocity_scale), 100)
                for axis, velocity in velocities.items()
            },
        )

    def set_velocity(self, axis, velocity):
        velocity *= 10
        self.set_position(
            axis,
            self.positions[axis] + velocity * self.position_scale,
            speed=max(abs(velocity) * self.velocity_scale, 5)
        )

    def go_home(self):
        self.set_positions(self._home_position())

    def go_random(self):
        for axis in BOUNDS:
            self.set_position(
                axis, random.randrange(BOUNDS[axis][0], BOUNDS[axis][1], 1)
            )
Ejemplo n.º 24
0
class FtdiSyncInterface:
    ##################################################################
    # Construction
    ##################################################################
    def __init__(self, iface=None):
        self.interface = iface
        self.target = None
        self.prog_cb = None
        self.CMD_NOP = 0x0
        self.CMD_WR = 0x1
        self.CMD_RD = 0x2
        self.CMD_GP_WR = 0x3
        self.CMD_GP_RD = 0x4
        self.HDR_SIZE = 6
        self.MAX_SIZE = 255
        self.BLOCK_SIZE_WR = 64  # Really 2048
        self.BLOCK_SIZE_RD = 64
        self.MAGIC_ADDR = 0xF0000000

        # User specified (device_id)
        self.dev_id = None
        if iface != None and iface != "":
            self.dev_id = iface

    ##################################################################
    # set_progress_cb: Set progress callback
    ##################################################################
    def set_progress_cb(self, prog_cb):
        self.prog_cb = prog_cb

    ##################################################################
    # connect: Open serial connection
    ##################################################################
    def connect(self):
        self.target = Device(device_id=self.dev_id, interface_select=1)
        self.target.flush()
        time.sleep(0.01)

        BITMODE_SYNCFF = 0x40
        SIO_RTS_CTS_HS = (0x1 << 8)
        self.target.ftdi_fn.ftdi_set_bitmode(0, BITMODE_SYNCFF)
        self.target.ftdi_fn.ftdi_setflowctrl(SIO_RTS_CTS_HS)
        self.target.flush()

    ##################################################################
    # write: Write a block of data to a specified address
    ##################################################################
    def write(self, addr, data, length, addr_incr=True, max_block_size=-1):
        # Connect if required
        if self.target == None:
            self.connect()

        # Write blocks
        idx = 0
        remainder = length

        if self.prog_cb != None:
            self.prog_cb(0, length)

        if max_block_size == -1:
            max_block_size = self.BLOCK_SIZE_WR

        while remainder > 0:
            l = max_block_size
            if l > remainder:
                l = remainder

            cmd = bytearray(2 + 4 + l)
            cmd[0] = (((l >> 8) & 0xF) << 4) | self.CMD_WR
            cmd[1] = l & 0xFF
            cmd[2] = (addr >> 24) & 0xFF
            cmd[3] = (addr >> 16) & 0xFF
            cmd[4] = (addr >> 8) & 0xFF
            cmd[5] = (addr >> 0) & 0xFF

            for i in range(l):
                cmd[6 + i] = data[idx]
                idx += 1

            # Write to interface
            self.target.write(cmd)

            # Update display
            if self.prog_cb != None:
                self.prog_cb(idx, length)

            if addr_incr:
                addr += l
            remainder -= l

    ##################################################################
    # read: Read a block of data from a specified address
    ##################################################################
    def read(self, addr, length, addr_incr=True, max_block_size=-1):
        # Connect if required
        if self.target == None:
            self.connect()

        idx = 0
        remainder = length
        data = bytearray(length)

        if self.prog_cb != None:
            self.prog_cb(0, length)

        if max_block_size == -1:
            max_block_size = self.BLOCK_SIZE_RD

        while remainder > 0:
            l = max_block_size
            if l > remainder:
                l = remainder

            cmd = bytearray(2 + 4)
            cmd[0] = (((l >> 8) & 0xF) << 4) | self.CMD_RD
            cmd[1] = l & 0xFF
            cmd[2] = (addr >> 24) & 0xFF
            cmd[3] = (addr >> 16) & 0xFF
            cmd[4] = (addr >> 8) & 0xFF
            cmd[5] = (addr >> 0) & 0xFF

            # Write to serial port
            self.target.write(cmd)

            # Read block response
            for i in range(l):

                x = bytearray()
                while len(x) == 0:
                    x = self.target.read(1)

                data[idx] = ord(x) & 0xFF
                idx += 1

            # Update display
            if self.prog_cb != None:
                self.prog_cb(idx, length)

            if addr_incr:
                addr += l
            remainder -= l

        return data

    ##################################################################
    # read32: Read a word from a specified address
    ##################################################################
    def read32(self, addr):
        # Connect if required
        if self.target == None:
            self.connect()

        # Send read command
        cmd = bytearray([
            self.CMD_RD, 4, (addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
            (addr >> 8) & 0xFF, (addr >> 0) & 0xFF
        ])
        self.target.write(cmd)

        value = 0
        idx = 0
        while (idx < 4):
            b = self.target.read(1)
            value |= (ord(b) << (idx * 8))
            idx += 1

        return value

    ##################################################################
    # write32: Write a word to a specified address
    ##################################################################
    def write32(self, addr, value):
        # Connect if required
        if self.target == None:
            self.connect()

        # Send write command
        cmd = bytearray([
            self.CMD_WR, 4, (addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
            (addr >> 8) & 0xFF, (addr >> 0) & 0xFF, (value >> 0) & 0xFF,
            (value >> 8) & 0xFF, (value >> 16) & 0xFF, (value >> 24) & 0xFF
        ])
        self.target.write(cmd)

    ##################################################################
    # read_gpio: Read GPIO bus
    ##################################################################
    def read_gpio(self):
        # Connect if required
        if self.target == None:
            self.connect()

        # Send read command
        cmd = bytearray([self.CMD_GP_RD])
        self.target.write(cmd)

        return ord(self.target.read(1))

    ##################################################################
    # write_gpio: Write a byte to GPIO
    ##################################################################
    def write_gpio(self, value):
        # Connect if required
        if self.target == None:
            self.connect()

        # Send write command
        cmd = bytearray([self.CMD_GP_WR, (value >> 0) & 0xFF])
        self.target.write(cmd)
Ejemplo n.º 25
0
import paho.mqtt.client as mqtt
import json
from pylibftdi import Device, USB_PID_LIST, USB_VID_LIST

from config import MQTT_HOST

USB_VID_LIST.append(0x1321)
USB_PID_LIST.append(0x1001)

dev = Device(mode='t')
dev.baudrate = 57600
dev.open()


def run_command(cmd):
    if cmd != '':
        dev.flush()
        print('TX: ' + cmd)
        dev.writelines(cmd + '\r')
        out = ''
        while out == '':
            out = dev.readline()
        print('RX: ' + out)


def to_command(obj):
    cmds = []
    for input in obj:
        cmd = 'xpgn(' + input + ',*)='
        # print('Input: ' + input)
        # print(obj[input])
Ejemplo n.º 26
0
 def __init__(self):
     self.ser = Device(mode='b', lazy_open=True)
Ejemplo n.º 27
0
 def __init__(self):
     self.device = Device(device_id="64drive USB device")
Ejemplo n.º 28
0
class HondaECU(object):

	def __init__(self, device_id=None):
		super(HondaECU, self).__init__()
		self.device_id = device_id
		self.dev = None
		self.error = 0
		self.resets = 0
		self.reset()

	def reset(self):
		if self.dev != None:
			del self.dev
			self.dev = None
		self.dev = Device(self.device_id)

	def setup(self):
		self.dev.ftdi_fn.ftdi_usb_reset()
		self.dev.ftdi_fn.ftdi_usb_purge_buffers()
		self.dev.ftdi_fn.ftdi_set_line_property(8, 1, 0)
		self.dev.baudrate = 10400

	def _break(self, ms, debug=False):
		self.dev.ftdi_fn.ftdi_set_bitmode(1, 0x01)
		self.dev._write(b'\x00')
		time.sleep(ms)
		self.dev._write(b'\x01')
		self.dev.ftdi_fn.ftdi_set_bitmode(0, 0x00)
		self.dev.flush()

	def init(self, debug=False):
		ret = False
		self._break(.070)
		time.sleep(.130)
		self.dev.flush()
		info = self.send_command([0xfe],[0x72], debug=debug, retries=0) # 0xfe <- KWP2000 fast init all nodes ?
		if info != None and ord(info[0]) > 0:
			if ord(info[2]) == 0x72:
				ret = True
		return ret

	def kline(self):
		b = create_string_buffer(2)
		self.dev.ftdi_fn.ftdi_poll_modem_status(b)
		return b.raw[1] & 16 == 0

	def send(self, buf, ml, timeout=.5):
		self.dev.flush()
		msg = "".join([chr(b) for b in buf]).encode("latin1")
		self.dev._write(msg)
		r = len(msg)
		to = time.time()
		while r > 0:
			r -= len(self.dev._read(r))
			if time.time() - to > timeout: return None
		buf = bytearray()
		r = ml+1
		while r > 0:
			tmp = self.dev._read(r)
			r -= len(tmp)
			buf.extend(tmp)
			if time.time() - to > timeout: return None
		r = buf[-1]-ml-1
		while r > 0:
			tmp = self.dev._read(r)
			r -= len(tmp)
			buf.extend(tmp)
			if time.time() - to > timeout: return None
		return buf

	def send_command(self, mtype, data=[], retries=10, debug=False):
		msg, ml, dl = format_message(mtype, data)
		first = True
		while first or retries > 0:
			first = False
			if debug:
				sys.stderr.write("> [%s]" % ", ".join(["%02x" % m for m in msg]))
			resp = self.send(msg, ml)
			ret = None
			if resp == None:
				if debug:
					sys.stderr.write(" !%d \n" % (retries))
				retries -= 1
				time.sleep(0)
				continue
			else:
				if debug:
					sys.stderr.write("\n")
			if debug:
				sys.stderr.write("< [%s]" % ", ".join(["%02x" % r for r in resp]))
			invalid = (resp[-1] != checksum8bitHonda([r for r in resp[:-1]]))
			if invalid:
				if debug:
					sys.stderr.write(" !%d \n" % (retries))
				retries -= 1
				time.sleep(0)
				continue
			else:
				if debug:
					sys.stderr.write("\n")
			sys.stderr.flush()
			rmtype = resp[:ml]
			rml = resp[ml:(ml+1)]
			rdl = ord(rml) - 2 - len(rmtype)
			rdata = resp[(ml+1):-1]
			return (rmtype, rml, rdata, rdl)

	def do_init_recover(self, debug=False):
		self.send_command([0x7b], [0x00, 0x01, 0x03], debug=debug)
		self.send_command([0x7b], [0x00, 0x01, 0x01], debug=debug)
		self.send_command([0x7b], [0x00, 0x01, 0x02], debug=debug)
		self.send_command([0x7b], [0x00, 0x01, 0x03], debug=debug)
		self.send_command([0x7b], [0x00, 0x02, 0x76, 0x03, 0x17], debug=debug) # seed/key?
		self.send_command([0x7b], [0x00, 0x03, 0x75, 0x05, 0x13], debug=debug) # seed/key?

	def do_init_write(self, debug=False):
		# is this the command to erase the ECU?
		self.send_command([0x7d], [0x01, 0x01, 0x00], debug=debug)
		self.send_command([0x7d], [0x01, 0x01, 0x01], debug=debug)
		self.send_command([0x7d], [0x01, 0x01, 0x02], debug=debug)
		self.send_command([0x7d], [0x01, 0x01, 0x03], debug=debug)
		self.send_command([0x7d], [0x01, 0x02, 0x50, 0x47, 0x4d], debug=debug) # seed/key?
		self.send_command([0x7d], [0x01, 0x03, 0x2d, 0x46, 0x49], debug=debug) # seed/key?

	def do_pre_write(self, debug=False):
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)
		time.sleep(11)
		self.send_command([0x7e], [0x01, 0x02], debug=debug)
		self.send_command([0x7e], [0x01, 0x03, 0x00, 0x00], debug=debug)
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)
		self.send_command([0x7e], [0x01, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff], debug=debug) # password?
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)
		self.send_command([0x7e], [0x01, 0x0e, 0x01, 0x90], debug=debug)
		self.send_command([0x7e], [0x01, 0x01, 0x01], debug=debug)
		self.send_command([0x7e], [0x01, 0x04, 0xff], debug=debug)
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)

	def do_pre_write_wait(self, debug=False):
		while True:
			info = self.send_command([0x7e], [0x01, 0x05], debug=debug)
			if info[2][1] == 0x00:
				break
		self.send_command([0x7e], [0x01, 0x01, 0x00], debug=debug)
Ejemplo n.º 29
0
#! /usr/bin/python

import sys, os

#import pylibftdi
from pylibftdi import Driver, Device

try:
  dev_list  = Driver().list_devices()
  if len(dev_list) != 0:
    print "\n\nFollowing devices found: \n"
    for device_ in dev_list:
      print device_
    
    dev = Device(device_id="FTZ17IRO", mode='b', interface_select=2)
    
    dev.open()
    
    tx_data = bytearray(range(0, 256))
    dev.write(tx_data)
    
    rx_data = bytearray(dev.read(257))#, timeout = 0))
    
    if len(rx_data) == 256 :
      print "\n\n[Test] Test 1 Passed: Sent 256 bytes of data, received 256 bytes of data"
    
    failed = False
    for i in range(256):
      if ((tx_data[i]+1)%256) != rx_data[i]:
        print "[Test] Test 2: Data verification failed! , tx_data : ", tx_data[i], " =/= rx_data : ", rx_data[i]
        failed = True	
			toSend = 'S%s+' % msg['S']
			print '>> %s' % toSend.encode('string_escape')
			self.tellstick.write(toSend)
		time.sleep(2) # Make sure you sleep or else it won't like getting another command so soon!

	def go(self):
		self.threatellStick = threading.Thread(target=self.writer)
		self.threatellStick.daemon = True
		self.threatellStick.start()

		# We wait for the writer to be actually running (but not yet
		# writing anything) before we start the reader.
		self.running.wait()
		self.thread2 = threading.Thread(target=self.reader)
		self.thread2.daemon = True
		self.thread2.start()

	def join(self):
		# Use of a timeout allows Ctrl-C interruption
		self.threatellStick.join(timeout=1e6)
		self.thread2.join(timeout=1e6)

if __name__ == '__main__':

	tellStick = TellStick(mode='t')
	tellStick.flush()
	app = Application(tellStick)
	app.go()
	app.join()
	tellStick.flush()
Ejemplo n.º 31
0
#!/usr/bin/env python
import pygame
from math import floor
from pylibftdi import Device  # I2C over USB
import time

# import servo
dev = Device(mode="b")
dev.baudrate = 9600

# allow multiple joysticks
joy = []


def fix(bits):
    if bits & 0b00100000:
        return 63 - bits
    else:
        return bits


# handle joystick event
def handleJoyEvent(e):
    if e.type == pygame.JOYAXISMOTION:
        axis = "unknown"
        if e.dict["axis"] == 0:
            axis = "X"
            bits = 0b10000000  # Throw away; don't change anything

        if e.dict["axis"] == 1:
            axis = "Y"
Ejemplo n.º 32
0
from pylibftdi import Device

with Device(mode='t') as dev:
    dev.baudrate = 115200
    dev.write('Hello World')
Ejemplo n.º 33
0
class Dongle(object):
    '''
    
    For full description visit: http://docs.s-crib.com/doku.php/scramble_scrib_-_api_specification 
    
    Management commands
    GETINITKEY  host computer can request initialisation key, it will be typed after a button is pressed;
    GETPASSWD  requests one of the device's passwords.

    Status commands
    GETID  host computer requests the device's ID
    ENGETID  request the device's ID, the response is encrypted
    GETCOUNTER  returns the number of SCRAMBLE requests served

    Execution commands
    SCRAMBLE  protect a password;
    ENSCRAMBLE  protect a password that is sent encrypted

    General Rules and Security Policy
    1. Passwords contain characters in ASCII encoding.
    2. Management commands can only be executed before the first execution command is served.
    3. The maximum length of commands is 160 characters, including <new line>.
    4. All letters must be sent as capitals (with the exception of passwords), 
       the device replies with capital letters only as well.
    5. Commands must start immediately after newline, command and parameters must be separated 
       with exactly one space.
    6. The device does only necessary checks of commands and parameters to 
       protect itself against malformed commands.
    7. The device uses 3 passwords, each is 32 characters long:
        a, Password 2  for scrambling;
        b, Password 3  computes -time- to EXOR with salt before scrambling; and
        c, Password 4  encryption of parameters for commands with prefix EN.
    
    '''
    _BLOCK_SIZE = 16
    _READ_TIMEOUT = 2 # in seconds
    space = 1
    operationCounterLen = 8  + space # length of the postfix - appended to all non encrypted command responses
    scrambleLength = 64
        
    '''
    GETID command returns the device's ID. This is required to recover passwords
    from the initialisation key - online service is available here: https://my.s-crib.com/
    '''
    getIdText = "GETID\n"
    getIdTextLen  = 16 +operationCounterLen
        
    '''
    GETCLUSTER allows the host computer to request the device's cluster ID - identifies its set of passwords.
    '''
    getClusterText = "GETCLUSTER\n"
    getClusterTextLen = 10 +operationCounterLen
        
    '''
    GETLOCKED command returns whether the device is locked - protects keys/passwords. 
    '''
    getLockedText = "GETLOCKED\n"
    getLockedTextLen  = 1 +operationCounterLen
                
    '''
    GETINITKEY allows the host computer to request the device's initialisation key. 
    This can be printed out and used for pas < missing text on web site ;0)
    '''
    getInitKeyText = "GETINITKEY\n"
    getInitKeyTextLen = 48 +operationCounterLen
        
    '''
    GETPASSWD allows the host computer to request the device's passwords (2/3/4) for backup.
    '''
    getPasswordText = "GETPASSWD %d\n"
    getPasswordTextLen = 32 +operationCounterLen
        
    '''
    GETCOUNTER command returns the order number of the last command. 
    This counter is incremented with each command sent to the device. 
    It is kept in volatile memory and reset to nought each time the device loses power supply.
    '''
    getCounterText = "GETCOUNTER\n"
    getCounterTextLen = 16
        
    '''
    GETDELAY allows the host computer to set the current delay set on the device. 
    This delay may increase protection against brute-force attacks. 
    The delay is between 0 and 99. You need to experiment to get the delay length in milliseconds. 
    '''
    getDelayText = "GETDELAY\n"
    getDelayTextLen = 2 +operationCounterLen
        
    '''
    ENGETID is the encrypted variant of the GETID command. This can be used when the device is on another 
    physical server and some kind of encryption is required. 
    '''
    enGetIdText = "ENGETID %s\n"
    enGetIdTextLen = 64 +operationCounterLen
        
    '''
    ENSCRAMBLE is the encrypted variant of the SCRAMBLE command. 
    All parameters of SCRAMBLE are prefixed with a hexadecimal 
    counter of 16 digits and padded with spaces to create 96 characters' 
    string that is encrypted. Encryption used to protect parameters 
    is AES256-CBC and it uses Password 4
    '''
    enScrambleText = "ENSCRAMBLE %s\n"
    enScrambleTextLen = 128 +operationCounterLen
        
    '''
    This is the actual operation command. Password must not contain space or new line. 
    The salt_length is between 0 and 32 and denotes the length of the returned string. 
    The string is of hexadecimal digits and each digit gives 4 bits of entropy.
    The salt is an optional parameter with the minimum length of <salt_length>. 
    If the <salt> is missing and <salt_length> is non-zero, the device will generate 
    a new random <salt>. 
    '''
    scrambleText = "SCRAMBLE %s %02d %s\n"
    scrambleTextLen =operationCounterLen  # Length will need to adjusted at time of call
  
    def __init__(self,deviceId=""):
        '''
        Constructor
        '''
        self._ID = None
        self._HWID = None
        self._Cluster = None
        
        self._firstCmd = True
        self._errorFlag = False
        self._errorMSg = ""
        self._stick = None
        if deviceId == "":
            log_trace('C', '0067', "No deviceID provided", traceback=traceback.print_stack())
            pass #self.stick = Device(mode = "t")
        else:
            try:
                self._stick = Device(device_id=deviceId,mode = "t")
                self._stick.open()
                #one call of the baudrate setter does not always work 
                self._stick.baudrate = 3000000
            except:
                log_trace('E', '0068', "Error when opening new device", ID=deviceId, exception=', '.join(sys.exc_info()[0]))
                if self._stick:
                    self._stick.close()
                self._stick = None
                #ERR408
                return
            self._HWID = deviceId
            self._ID = self.GETID()
            if self._ID:
                self._ID = self._ID.split()[0]
            else:
                log_trace('E', '0069', "GETID() returned no data", HWID=deviceId)
                self._stick.close()
                self._stick = None
                # ERR405
                return
                
            self._Cluster = self.GETCLUSTER()
            if self._Cluster:
                self._Cluster = self._Cluster.split()[0]
            else:
                log_trace('E', '0070', "GETCLUSTER() returned no data", HWID=deviceId)
                self._stick.close()
                self._stick = None
                #ERR406
                return
            
            if (self._ID[:3]=="ERR") or (self._Cluster[:3]=="ERR"):
                log_trace('E', '0071', "Device initialisation returned an error (GETID or GETCLUSTER)", HWID=deviceId, ID=self._ID, cluster=self._Cluster)
                self._stick.close()
                self._stick = None

    def exists(self):
        log_trace('D', '0072', "exists() called", ID=self._ID)
        if self._stick:
            return True
        else:
            return False

    ''' 
       Returns a list of tuples:
        - first item: a colon-separated vendor:product:serial summary of detected devices
        - second item: serial number - HWID
    '''
    @staticmethod  
    def listDevices():
        log_trace('D', '0073', "listDevices() called", detail="n/a")
        dev_list = []
        dev_dict = {}
        devices = None
        try:
            #FTDI returns a list of triplets - (vendor, name, HWID)
            devices =  Driver().list_devices()
        except AttributeError, e:
            # ERR_ENUMERATE ERR403
            log_trace('E', '0074', "Error when enumerating devices - Attribute Error", exception=e)
            if  not devices:
                return None
        except :
Ejemplo n.º 34
0
from pylibftdi import Device, USB_PID_LIST, USB_VID_LIST

USB_VID_LIST.append(0x1321)
USB_PID_LIST.append(0x1001)

dev = Device(mode='t')
dev.baudrate = 57600
dev.open()
cmd = 'serial?'
while cmd != 'quit':
    if cmd != '':
        dev.flush_input()
        dev.writelines(cmd + '\r')
    out = ''
    while out == '':
        out = dev.readline()
    print(out)
    cmd = input('Type command: ')
Ejemplo n.º 35
0
	def reset(self):
		if self.dev != None:
			del self.dev
			self.dev = None
		self.dev = Device(self.device_id)
Ejemplo n.º 36
0
class Py64drive:
    def __init__(self):
        self.device = Device(device_id="64drive USB device")

    def _send_cmd(self, cmd, params):
        txbuf = struct.pack(">B3s",cmd,b"CMD")
        if len(params) >= 1:
            txbuf += struct.pack(">L",params[0])
        if len(params) >= 2:
            txbuf += struct.pack(">L",params[1])

        self.device.write(txbuf)

    def _recv_resp(self):
        rxbuf = self.device.read(4)
        return struct.unpack(">L", rxbuf)

    def _recv_ver_resp(self):
        rxbuf = self.device.read(8)
        return struct.unpack(">L4s", rxbuf)

    def _recv_success(self,command):
        while True:
            rxbuf = self.device.read(4)
            if rxbuf: break

        if rxbuf != b"CMP" + bytes([command]):
            #print("Got {}, expected CMP{}",rxbuf,command,file=sys.stderr)
            return False

        return True

    def load_image(self, data, bank, ram_addr=0):
        length = len(data)

        if length % 512:
            #print("File was truncated during loading.", file=sys.stderr)
            length -= length % 512

        for offset in range(0, length, CHUNK_SIZE):
            size = min(CHUNK_SIZE, length - offset)

            block = data[offset:offset+size]

            self._send_cmd(0x20, (ram_addr + offset, (bank << 24) | (size & 0xffffff)))
            self.device.write(block)

            self._recv_success(0x20)

    def dump_image(self, length, bank, ram_addr=0):		
        data = b""

        if length % 512:
            #print("File was truncated during dumping.", file=sys.stderr)
            length -= length % 512

        for offset in range(0, length, CHUNK_SIZE):
            size = min(CHUNK_SIZE, length - offset)

            self._send_cmd(0x30, (ram_addr + offset, (bank << 24) | (size & 0xffffff)))
            data += self.device.read(size)

            self._recv_success(0x30)

        return data

    def set_save(self, save_type):
        self._send_cmd(0x70, (save_type,))
        self._recv_success(0x70)

    def read_version(self):
        self._send_cmd(0x80,())

        val,magic = self._recv_ver_resp()
        if val == 0 or magic != b"UDEV":
            #print("Incorrect 64drive version reported.", file=sys.stderr)
            return False

        self._recv_success(0x80)
        return True

    def pi_write_block(self,*args):
        raise NotImplementedError("Not implemented yet")

    def pi_write_block_long(self,*args):
        raise NotImplementedError("Not implemented yet")

    def pi_read_int32(self):
        raise NotImplementedError("Not implemented yet")

    def pi_write_int32(self,num):
        raise NotImplementedError("Not implemented yet")
Ejemplo n.º 37
0
class Ecu:

   def __init__(self):
      self.ser = Device(mode='b', lazy_open=True)


   def bbang(self, bba):
      # Take the one-byte address to "bit bang" and bang the port
      self.bba = bba
      self.bbser = BitBangDevice()
      self.bbser.open()
      self.bbser.direction = 0x01
      self.bbser.port = 1
      time.sleep(.5)
      self.bbser.port = 0
      outstr = "><"
      sys.stdout.write('\r' + outstr)
      sys.stdout.flush()
      time.sleep(.2)
      bbbitmask = 1
      for i in range(8):
         if (self.bba[0] & bbbitmask) > 0:
            outbit = 1
         else:
            outbit = 0   
         self.bbser.port = outbit
         outstr = ">" + str(outbit) + outstr[1:] 
         sys.stdout.write('\r' + outstr)
         sys.stdout.flush()
         bbbitmask = bbbitmask * 2
         time.sleep(.2)
      self.bbser.port = 1
      sys.stdout.write("\n")
      self.bbser.close()

   def initialize(self, connect):
      self.connect = connect
      if self.connect == "SLOW-0x11":
         self.ser.close()
         time.sleep(.5)

         self.ecuconnect = False
         while self.ecuconnect == False:
            print("Attempting ECU connect: " + self.connect )

            # Bit bang the K-line
            bbseq = [ 0x11 ]
            self.bbang(bbseq)
            self.ser.open()
            self.ser.ftdi_fn.ftdi_set_line_property(8, 1, 0)
            self.ser.baudrate = 10400
            self.ser.flush()

            # Wait for ECU response to bit bang
            waithex = [ 0x55, 0xef, 0x8f, 1 ]
            self.waitfor(waithex)
            # Wait a bit
            time.sleep(.026)

            # Send 0x70
            self.send([ 0x70 ])
   
            # 0xee means that we're talking to the ECU
            waithex = [ 0xee, 1 ]
            response = self.waitfor(waithex)
            if response[0] == True:
                self.ecuconnect = True
            else:
                print("ECU Connect Failed.  Retrying.")

   def waitfor(self, wf):
      # This was used for debugging and really is only used for the init at this point.
      # wf should be a list with the timeout in the last element
      self.wf = wf
      isfound = False
      idx = 0
      foundlist = []
      capturebytes = []
      to = self.wf[-1]
      timecheck = time.time()
      while (time.time() <= (timecheck+to)) & (isfound == False): 
         try:
            recvbyte = self.recvraw(1)
            if recvbyte != "":
               recvdata = ord(recvbyte)
               capturebytes = capturebytes + [ recvdata ]
               if recvdata == self.wf[idx]: 
                  foundlist = foundlist + [ recvdata ]
                  idx = idx + 1
               else: 
                  foundlist = []
                  idx = 0
               if idx == len(self.wf)-1:
                  isfound = True
         except:
            print('error')
            break
      return [ isfound, foundlist, capturebytes ]

   def send(self, sendlist):
      self.sendlist = sendlist
      # Puts every byte in the sendlist out the serial port
      for i in self.sendlist:
         self.ser.write(chr(i))

   def recvraw(self, bytes):
      self.bytes = bytes
      recvdata = self.ser.read(self.bytes)
      return recvdata

   def recv(self, bytes):
      self.bytes = bytes
      isread = False
      while isread == False:
         recvbyte = self.ser.read(self.bytes)
         if recvbyte != "":
            recvdata = recvbyte
            isread = True
      return recvdata      

   def sendcommand(self, sendlist):
      # Wraps raw KWP command in a length byte and a checksum byte and hands it to send()
      self.sendlist = sendlist
      csum = 0
      self.sendlist = [len(self.sendlist)] + self.sendlist 
      csum = self.checksum(self.sendlist)
      self.sendlist = self.sendlist + [csum] 
      self.send(self.sendlist)
      cmdval = self.commandvalidate(self.sendlist)
      return cmdval

   def commandvalidate(self, command):
      # Every KWP command is echoed back.  This clears out these bytes.
      self.command = command
      cv = True
      for i in range(len(self.command)):
         recvdata = self.recv(1)
         if ord(recvdata) != self.command[i]:
            cv = cv & False
      return cv   

   def checksum(self, checklist):
      # Calculates the simple checksum for the KWP command bytes.
      self.checklist = checklist
      csum = 0
      for i in self.checklist:
         csum = csum + i
      csum = (csum & 0xFF) % 0xFF
      return csum

   def getresponse(self):
      # gets a properly formated KWP response from a command and returns the data. 
      debugneeds = 4
      numbytes = 0
      while numbytes == 0:     # This is a hack because sometimes responses have leading 0x00's.  Why?  This removes them.
         numbytes = ord(self.recv(1))
      gr = [ numbytes ]
      if debug >= debugneeds: print("Get bytes: " + hex(numbytes))
      for i in range(numbytes):
         recvdata = ord(self.recv(1))
         if debug >= debugneeds: print("Get byte" + str(i) + ": " + hex(recvdata))
         gr = gr + [ recvdata ]
      checkbyte = self.recv(1)
      if debug >= debugneeds: print(gr)
      if debug >= debugneeds: print("GR: " + hex(ord(checkbyte)) + "<-->" + hex(self.checksum(gr))) 
      return (gr + [ ord(checkbyte) ])

   def readecuid(self, paramdef):      
      # KWP2000 command to pull the ECU ID
      self.paramdef = paramdef
      debugneeds = 4
      reqserviceid = [ 0x1A ]
      sendlist = reqserviceid + self.paramdef
      if debug >= debugneeds: print( sendlist )
      self.sendcommand(sendlist)
      response = self.getresponse()
      if debug >= debugneeds: print(response)
      return response

   def stopcomm(self):
      # KWP2000 command to tell the ECU that the communications is finished
      stopcommunication = [ 0x82 ]
      self.sendcommand(stopcommunication)
      response = self.getresponse()
      return response

   def startdiagsession(self, bps):
      # KWP2000 setup that sets the baud for the logging session
      self.bps = bps
      startdiagnosticsession = [ 0x10 ]
      setbaud = [ 0x86 ]  #Is this the actual function of 0x86?
   #   if self.bps == 10400:
   #      bpsout = [ 0x?? ]
   #   if self.bps == 14400:
   #      bpsout = [ 0x?? ]
      if self.bps == 19200:
         bpsout = [ 0x30 ]
      if self.bps == 38400:
         bpsout = [ 0x50 ]
      if self.bps == 56000:
         bpsout = [ 0x63 ]
      if self.bps == 57600:
         bpsout = [ 0x64 ]
   #   if self.bps == 125000:
   #      bpsout = [ 0x?? ]
      sendlist = startdiagnosticsession + setbaud + bpsout
      self.sendcommand(sendlist)
      response = self.getresponse()
      self.ser.baudrate = self.bps
      time.sleep(1)
      return response

   def accesstimingparameter(self, params):
      # KWP2000 command to access timing parameters
      self.params = params
      accesstiming_setval = [ 0x083, 0x03 ]
      accesstiming = accesstiming_setval + self.params
      sendlist = accesstiming
      self.sendcommand(sendlist)
      response = self.getresponse()
      return response
   
   def readmembyaddr(self, readvals):
      # Function to read an area of ECU memory.
      debugneeds = 4
      self.readvals = readvals
      rdmembyaddr = [ 0x23 ]
      sendlist = rdmembyaddr + self.readvals
      if debug >= debugneeds: print("readmembyaddr() sendlist: " + sendlist)
      self.sendcommand(sendlist)
      response = self.getresponse()
      if debug >= debugneeds: print("readmembyaddr() response: " + response)
      return response

   def writemembyaddr(self, writevals):
      # Function to write to an area of ECU memory.
      debugneeds = 4
      self.writevals = writevals
      wrmembyaddr = [ 0x3D ]
      sendlist = wrmembyaddr + self.writevals
      if debug >= debugneeds: print("writemembyaddr() sendlist: " + sendlist)
      self.sendcommand(sendlist)
      response = self.getresponse()
      if debug >= debugneeds: print("writemembyaddr() response: " + response)
      return response

   def testerpresent(self):
      # KWP2000 TesterPresent command
      tp = [ 0x3E ]
      self.sendcommand(tp)
      response = self.getresponse()
      return response

   def setuplogrecord(self, logline):
      # KWP2000 command to access timing parameters
      self.logline = logline
      response = []
      sendlist = [ 0xb7 ]                           # is 0xB7 the "locator?"
      sendlist = sendlist + [ 0x03 ]           # Number of bytes per field ?
      sendlist = sendlist + self.logline                
      self.sendcommand(sendlist)
      response = self.getresponse()
      return response

   def getlogrecord(self):
      # Command to request a logging record
      gr = [ 0xb7 ]
      self.sendcommand(gr)
      response = self.getresponse()
      return response

   def sendhexstring(self, dumpstring):
      # Takes a list of characters as a string, turns every two characters into a hex byte and sends it raw.
      # used as needed for dev/test/debug
      self.dumpstring = dumpstring
      for i in range(len(self.dumpstring)/2):
         self.send([ int('0x'+self.dumpstring[i*2:(i*2)+2],16) ])
Ejemplo n.º 38
0
class Ecu:
    def __init__(self):
        self.ser = Device(mode='b', lazy_open=True)

    def slowInit11(self):
        # Take the one-byte address to "bit bang" and bang the port
        self.bbser = BitBangDevice()
        print("beginning slow init")
        self.bbser.open()
        self.bbser.direction = 0x01
        self.bbser.port = 1
        time.sleep(.5)
        self.bbser.port = 0
        time.sleep(.2)
        self.bbser.port = 1
        time.sleep(.2)
        self.bbser.port = 0
        time.sleep(1.4)
        self.bbser.port = 1
        time.sleep(.2)
        self.bbser.close()
        print("slow init sent")

    def initialize(self, connect):
        self.connect = connect
        if self.connect == "SLOW-0x11":
            self.ser.close()
            time.sleep(.5)

            self.ecuconnect = False
            while self.ecuconnect == False:
                print("Attempting ECU connect: " + self.connect)

                # Bit bang the K-line
                self.slowInit11()
                self.ser.open()
                self.ser.ftdi_fn.ftdi_set_line_property(8, 1, 0)
                self.ser.baudrate = 10400
                self.ser.flush()

                # Wait for ECU response to bit bang
                waithex = [0x55, 0xef, 0x8f, 1]
                print("Wating for init response")
                response = self.waitfor(waithex)
                print(f"Init response: {hexlist(response[2])}")
                # Wait a bit
                time.sleep(.026)

                # Send 0x70
                self.send([0x70])

                # 0xee means that we're talking to the ECU
                waithex = [0xfe, 1]
                print("waiting for ECU reponse")
                response = self.waitfor(waithex)
                print(f"ecu connection response: {hexlist(response[2])}")
                if response[0] == True:
                    self.ecuconnect = True
                else:
                    print("ECU Connect Failed.  Retrying.")
                    return
                print("INIT done")

    def waitfor(self, wf):
        # This was used for debugging and really is only used for the init at this point.
        # wf should be a list with the timeout in the last element
        self.wf = wf
        isfound = False
        idx = 0
        foundlist = []
        capturebytes = []
        to = self.wf[-1]
        timecheck = time.time()
        while (time.time() <= (timecheck + to)) & (isfound == False):
            try:
                recvbyte = self.recvraw(1)
                if recvbyte != b"":
                    recvdata = ord(recvbyte)
                    capturebytes = capturebytes + [recvdata]
                    if recvdata == self.wf[idx]:
                        foundlist = foundlist + [recvdata]
                        idx = idx + 1
                    else:
                        foundlist = []
                        idx = 0
                    if idx == len(self.wf) - 1:
                        isfound = True
            except e:
                print([isfound, foundlist, capturebytes])
                print('error', e)
                break
        return [isfound, foundlist, capturebytes]

    def send(self, sendlist):
        self.sendlist = sendlist
        # Puts every byte in the sendlist out the serial port
        for i in self.sendlist:
            self.ser.write(chr(i))

    def recvraw(self, bytes):
        self.bytes = bytes
        recvdata = self.ser.read(self.bytes)
        return recvdata

    def recv(self, bytes):
        self.bytes = bytes
        isread = False
        while isread == False:
            recvbyte = self.ser.read(self.bytes)
            if recvbyte != b"":
                recvdata = recvbyte
                isread = True
        return recvdata

    def sendcommand(self, sendlist):
        # Wraps raw KWP command in a length byte and a checksum byte and hands it to send()
        self.sendlist = sendlist
        csum = 0
        self.sendlist = [len(self.sendlist)] + self.sendlist
        csum = self.checksum(self.sendlist)
        self.sendlist = self.sendlist + [csum]
        self.send(self.sendlist)
        print(f"sendcommand() sent: {hexlist(self.sendlist)}")
        cmdval = self.commandvalidate(self.sendlist)
        return cmdval

    def commandvalidate(self, command):
        # Every KWP command is echoed back.  This clears out these bytes.
        self.command = command
        cv = True
        for i in range(len(self.command)):
            recvdata = self.recv(1)
            if ord(recvdata) != self.command[i]:
                cv = cv & False
        return cv

    def checksum(self, checklist):
        # Calculates the simple checksum for the KWP command bytes.
        self.checklist = checklist
        csum = 0
        for i in self.checklist:
            csum = csum + i
        csum = (csum & 0xFF) % 0xFF
        return csum

    # used exclusivly for the errorhandling section
    def _raise(self, ex):
        raise ex

    def getresponse(self):
        # gets a properly formated KWP response from a command and returns the data.
        debugneeds = 4
        numbytes = 0
        # This is a hack because sometimes responses have leading 0x00's.  Why?  This removes them.
        while numbytes == 0:
            numbytes = ord(self.recv(1))
        gr = [numbytes]
        if debug >= debugneeds:
            print("Get bytes: " + hex(numbytes))
        for i in range(numbytes):
            recvdata = ord(self.recv(1))
            if debug >= debugneeds:
                print("Get byte" + str(i) + ": " + hex(recvdata))
            gr = gr + [recvdata]
        checkbyte = self.recv(1)
        if debug >= debugneeds:
            print(f"getresponse recieved: {hexlist(gr)}")
        if debug >= debugneeds:
            print("GR: " + hex(ord(checkbyte)) + "<-->" +
                  hex(self.checksum(gr)))
        if (gr[1] == 0x7f):
            return {  # returning the result so 0x78 (responsePending) can re-execute
                0x10:
                lambda: self._raise(Exception("generalReject", gr)),
                0x11:
                lambda: self._raise(Exception("busyRepeatRequest", gr)),
                0x12:
                lambda: self._raise(
                    Exception("subFunctionNotSupported / invalidFormat", gr)),
                0x21:
                lambda: self._raise(Exception("busyRepeatRequest", gr)),
                0x22:
                lambda: self._raise(
                    Exception("conditionsNotCorrectOrRequestSequenceError", gr)
                ),
                0x23:
                lambda: self._raise(Exception("routineNotComplete", gr)),
                0x31:
                lambda: self._raise(Exception("requestOutOfRange", gr)),
                0x33:
                lambda: self._raise(
                    Exception("securityAccessDenied / securityAccessRequested",
                              gr)),
                0x35:
                lambda: self._raise(Exception("invalidKey", gr)),
                0x36:
                lambda: self._raise(Exception("exceedNumberOfAttempts", gr)),
                0x37:
                lambda: self._raise(
                    Exception("requiredTimeDelayNotExpired", gr)),
                0x40:
                lambda: self._raise(Exception("downloadNotAccepted")),
                0x41:
                lambda: self._raise(Exception("improperDownloadType")),
                0x42:
                lambda: self._raise(
                    Exception("canNotDownloadToSpecifiedAddress", gr)),
                0x43:
                lambda: self._raise(
                    Exception("canNotDownloadNumberOfBytesRequested", gr)),
                0x50:
                lambda: self._raise(Exception("uploadNotAccepted", gr)),
                0x51:
                lambda: self._raise(Exception("improperUploadType", gr)),
                0x52:
                lambda: self._raise(
                    Exception("canNotUploadFromSpecifiedAddress", gr)),
                0x53:
                lambda: self._raise(
                    Exception("canNotUploadNumberOfBytesRequested", gr)),
                0x71:
                lambda: self._raise(Exception("transferSuspended", gr)),
                0x72:
                lambda: self._raise(Exception("transferAborted", gr)),
                0x74:
                lambda: self._raise(
                    Exception("illegalAddressInBlockTransfer", gr)),
                0x75:
                lambda: self._raise(
                    Exception("illegalByteCountInBlockTransfer", gr)),
                0x76:
                lambda: self._raise(Exception("illegalBlockTransferType", gr)),
                0x77:
                lambda: self._raise(
                    Exception("blockTransferDataChecksumError", gr)),
                0x78:
                self.getresponse,
                0x79:
                lambda: self._raise(
                    Exception("incorrectByteCountDuringBlockTransfer", gr)),
                0x80:
                lambda: self._raise(
                    Exception("serviceNotSupportedInActiveDiagnosticMode", gr)
                ),
                0x90:
                lambda: self._raise(Exception("noProgramm", gr)),
                0x91:
                lambda: self._raise(
                    Exception("requiredTimeDelayNotExpired", gr))
            }.get(
                gr[3], lambda: self._raise(
                    Exception("Generic KWP negative response", gr)))()
        return gr

    def readecuid(self, paramdef):
        #KWP2000 command to pull the ECU ID
        self.paramdef = paramdef
        debugneeds = 3
        response = self.sendcommand([0x10, 0x85])  # setup diag session
        reqserviceid = [0x1A]
        sendlist = reqserviceid + self.paramdef
        if debug >= debugneeds:
            print(f"readecuid sending: {hexlist(sendlist)}")
        self.sendcommand(sendlist)
        response = self.getresponse()
        if debug >= debugneeds:
            print(f"readecuid got: {hexlist(response)}")
        return response

    def securityAccessL3(self):
        ### Begin - level 3 security
        self.sendcommand([0x27, 0x03])
        response = self.getresponse()
        print(f"Seed: {hexlist(response)}")

        ## highBytes(uint8_t) = value(uint16_t) >> 8
        ## lowBytes(uint8_t) = value(uint16_t) & 0xff
        ## value(uint16_t) = (high << 8) + low

        seed = (response[3] << 24) + (response[4] << 16) + (
            response[5] << 8) + response[6]
        print(f"Seed: {seed}")

        key = seed + 12233  # standard VW access
        keyHex = [
            key >> 24 & 0xff, key >> 16 & 0xff, key >> 8 & 0xff, key & 0xff
        ]
        print(f"Seed: {hexlist(keyHex)}")
        self.sendcommand([0x27, 0x04] + keyHex)
        try:
            response = self.getresponse()  #sometimes this doesn't work
        except:
            response = self.getresponse()
        print(hexlist(response))
        if (response[3] != 0x34):
            raise Exception("failed to get L3 auth")

        print("End security level 3 access")

    # def securityAccessL1(self):
    #     pass
    #     ### Begin - Level 1 key/seed
    #     ## request seed 27 01
    #     self.sendcommand([0x27,0x01])
    #     response = self.getresponse()
    #     print(hexlist(response))
    #     # len? secreq  level    seed h    seed l    checksum
    #     # 0x06  0x67    0x01    0x6D 0x20 0xFC 0xB1   0xA8
    #     seedH = (response[3] << 8) + response[4]
    #     seedL = (response[5] << 8) + response[6]

    #     magicValue = 0x1c60020
    #     for count in range(5):
    #         tempstring = seedH &0x8000
    #         seedH = seedH << 1
    #         if(tempstring&0xFFFF == 0):
    #             temp2 = seedL&0xFFFF
    #             temp3 = tempstring&0xFFFF0000
    #             tempstring = temp2+temp3
    #             seedH = seedH&0xFFFE
    #             temp2 = tempstring&0xFFFF
    #             temp2 = temp2 >> 0x0F
    #             tempstring = tempstring&0xFFFF0000
    #             tempstring = tempstring+temp2
    #             seedH = seedH|tempstring
    #             seedL = seedL << 1
    #         else:
    #             tempstring = seedL+seedL
    #             seedH = seedH & 0xFFFE
    #             temp2 = tempstring & 0xFF #Same as EDC15 until this point
    #             temp3 = magicValue & 0xFFFFFF00
    #             temp2 = temp2 | 1
    #             magicValue = temp2 + temp3
    #             magicValue = magicValue & 0xFFFF00FF
    #             magicValue = magicValue | tempstring
    #             temp2 = seedL & 0xFFFF
    #             temp3 = tempstring & 0xFFFF0000
    #             temp2 = temp2 >> 0x0F
    #             tempstring = temp2 + temp3
    #             tempstring = tempstring | seedH
    #             magicValue = magicValue ^ 0x1289
    #             tempstring = tempstring ^ 0x0A22
    #             seedL = magicValue
    #             seedH = tempstring
    #     print(f"H:{seedH} L:{seedL}")
    #     ## high bytes = value >> 8
    #     ## low bytes = value & 0xff
    #     ## value = (high<<8) + low
    #     self.sendcommand([0x27,0x02, seedH & 0xff, seedH >>8, seedL & 0xff, seedL >> 8])
    #     # self.sendcommand([0x27,0x02, 0xff, 0xff, 0xff, 0xff])
    #     response = self.getresponse()

    def securityAccessL1(self):
        self.sendcommand([0x27, 0x01])
        response = self.getresponse()
        print(hexlist(response))
        seed = (response[3] << 24) + (response[4] << 16) + (
            response[5] << 8) + response[6]
        print(f"L1 seed: {seed}")
        '''
        for (byte i = 0; i < 5; i++) {
            if ((seed & 0x80000000) == 0x80000000) { // Check carry
                seed = (SEED_DATA[ecuID]) ^ ((seed << 1) | (seed >>> 31)); // rotate left and xor
            }
            else {
                seed = ((seed << 1) | (seed >>> 31)); // rotate left only
            }
        }
        return seed;
        '''
        magicValue = 0x1c60020

        def rshift(val, n):
            return (val >> n) & (0x7fffffff >> (n - 1))

        for x in range(5):
            if ((seed & 0x80000000) == 0x80000000):
                seed = magicValue ^ ((seed << 1) | rshift(seed, 31))
            else:
                seed = ((seed << 1) | rshift(seed, 31))
        print(f"L1 key: {seed}")
        keyHex = [
            seed >> 24 & 0xff, seed >> 16 & 0xff, seed >> 8 & 0xff, seed & 0xff
        ]
        self.sendcommand([0x27, 0x02] + keyHex)
        # self.sendcommand([0x27,0x02, 0xff, 0xff, 0xff, 0xff])
        return self.getresponse()

    def stopcomm(self):
        # KWP2000 command to tell the ECU that the communications is finished
        stopcommunication = [0x82]
        self.sendcommand(stopcommunication)
        response = self.getresponse()
        return response

    def startdiagsession(self, bps):
        # KWP2000 setup that sets the baud for the logging session
        self.bps = bps
        startdiagnosticsession = [0x10]
        sessionType = [0x86]
        #   if self.bps == 10400:
        #      bpsout = [ 0x?? ]
        #   if self.bps == 14400:
        #      bpsout = [ 0x?? ]
        if self.bps == 19200:
            bpsout = [0x30]
        if self.bps == 38400:
            bpsout = [0x50]
        if self.bps == 56000:
            bpsout = [0x63]
        if self.bps == 57600:
            bpsout = [0x64]
        if self.bps == 124800:
            bpsout = [0x87]
        if self.bps == 250000:
            bpsout = [0xA7]
        if (self.bps != 0):
            sendlist = startdiagnosticsession + sessionType + bpsout
        else:
            sendlist = startdiagnosticsession + sessionType
        self.sendcommand(sendlist)
        response = self.getresponse()
        self.ser.baudrate = self.bps
        time.sleep(1)
        return response

    def accesstimingparameter(self, params):
        # KWP2000 command to access timing parameters
        self.params = params
        accesstiming_setval = [0x83, 0x03]
        accesstiming = accesstiming_setval + self.params
        sendlist = accesstiming
        self.sendcommand(sendlist)
        response = self.getresponse()
        return response

    def readmembyaddr(self, readvals):
        # Function to read an area of ECU memory.
        debugneeds = 4
        self.readvals = readvals
        rdmembyaddr = [0x23]
        sendlist = rdmembyaddr + self.readvals
        if debug >= debugneeds:
            print("readmembyaddr() sendlist: " + hexlist(sendlist))
        self.sendcommand(sendlist)
        response = self.getresponse()
        if debug >= debugneeds:
            print("readmembyaddr() response: " + hexlist(response))
        return response

    def writemembyaddr(self, writevals):
        # Function to write to an area of ECU memory.
        debugneeds = 4
        self.writevals = writevals
        wrmembyaddr = [0x3D]
        sendlist = wrmembyaddr + self.writevals
        if debug >= debugneeds:
            print("writemembyaddr() sendlist: " + hexlist(sendlist))
        self.sendcommand(sendlist)
        response = self.getresponse()
        if debug >= debugneeds:
            print("writemembyaddr() response: " + hexlist(response))
        return response

    def testerpresent(self):
        # KWP2000 TesterPresent command
        tp = [0x3E]
        self.sendcommand(tp)
        response = self.getresponse()
        return response

    def setuplogrecord(self, logline):
        # KWP2000 command to access timing parameters
        self.logline = logline
        response = []
        sendlist = [0xb7]  # is 0xB7 the "locator?"
        sendlist = sendlist + [0x03]  # Number of bytes per field ?
        sendlist = sendlist + self.logline
        self.sendcommand(sendlist)
        response = self.getresponse()
        return response

    def getlogrecord(self):
        # Command to request a logging record
        gr = [0xb7]
        self.sendcommand(gr)
        response = self.getresponse()
        return response

    def sendhexstring(self, dumpstring):
        # Takes a list of characters as a string, turns every two characters into a hex byte and sends it raw.
        # used as needed for dev/test/debug
        self.dumpstring = dumpstring
        for i in range(len(self.dumpstring) / 2):
            self.send([int('0x' + self.dumpstring[i * 2:(i * 2) + 2], 16)])
Ejemplo n.º 39
0
 def __init__(self):
    self.ser = Device(mode='b', lazy_open=True)
Ejemplo n.º 40
0
        if (len(bytes) > 0):
            break
        time.sleep(0.1)

    print("Received", bytes)
    while (len(bytes) > 0):
        print(len(bytes))
        msg, bytes = get_msg(bytes)
        if (msg):
            print(msg)
            translate(msg)
            if INPUT:
                input()


with Device() as dev:
    dev.ftdi_fn.ftdi_set_bitmode(0xFF, 0x00)
    time.sleep(0.01)
    dev.ftdi_fn.ftdi_set_bitmode(0xFF, 0x40)

    dev.ftdi_fn.ftdi_set_latency_timer(5)
    dev.ftdi_fn.ftdi_setflowctrl(0)
    dev.ftdi_fn.ftdi_usb_purge_buffers()

    i1 = 0
    if RANDOM:
        while True:
            i2 = random.randint(0, 255)
            i3 = random.randint(0, 255)

            print(i1, i2, i3)
Ejemplo n.º 41
0
def midi_ftdi_dev():
    from pylibftdi import Device
    d = Device()
    d.baudrate = 31250
    return d
Ejemplo n.º 42
0
 def __init__(self):
     self.device = Device()
Ejemplo n.º 43
0
class MDB(object):
  def __init__(self, deviceid):
    self.__deviceid = deviceid
    self.__scaling = 0
    self.__coins = {}
    self.__deposited = 0

  def _ftdisend(self, data, mode):
    data_parity = self._parityOf(int(hexlify(data), 16))

    if data_parity == -1:
      if mode:
        #parity = serial.PARITY_EVEN
        parity = 2
      else:
        #parity = serial.PARITY_ODD
        parity = 1
    else:
      if mode:
        #parity = serial.PARITY_ODD
        parity = 1
      else:
        #parity = serial.PARITY_EVEN
        parity = 2
    try:
        self.__device = Device(self.__deviceid)
        self.__device.ftdi_fn.ftdi_set_line_property(8, 1, parity)
        self.__device.baudrate = 9600
        self.__device.write(data)
        self.__device.flush()
    except pylibftdi.FtdiError:
        print "FtdiError"
        self._ftdisend(data, mode)

  def _parityOf(self, int_type):
      parity = 0
      while (int_type):
          parity = ~parity
          int_type = int_type & (int_type - 1)
      return(parity)

  def _read(self):
    returndata = []
    for i in self.__device.read(100):
      returndata.append(i)

    return returndata

  def _send(self, data):
    mode = 1

    for element in data:
      self._ftdisend(element, mode)
      mode = 0

    self._ftdisend(self._calcchk(data), 0)

    time.sleep(0.1)
    return self._read()

  def _calcchk(self, data):
    sum = 0
    for byte in data:
        sum += int(hexlify(byte), 16)
    return unhexlify('{:02x}'.format(sum % 256))

  def _getbits(self, byte):
    return bin(int(hexlify(byte), 16))[2:].zfill(8)

# CoinChanger
  def reset(self):
    print "OUT: Reset"
    answer = self._send(data = ['\x08'])
    if (len(answer) == 1) and (answer[0] == '\x00'):
      print "IN : OK"
      #self.ack()
    else:
      print "IN: Fail"
      print answer

  def poll(self):
    print "OUT: Poll"
    answer = self._send(data = ['\x0B'])

    i = 0
    while i < len(answer):
      if answer[i] == '\x00':
        message = "ACK"
      elif answer[i] == '\xFF':
        message = "NACK"
      elif '\x01' <= answer[i] <= '\x0D':
        message = {
          '\x01': 'Escrow request - An escrow lever activation has been detected.',
          '\x02': 'Changer Payout Busy - The changer is busy activating payout devices',
          '\x03': 'No Credit - A coin was validated but did not get to the place in the system when credit is given',
          '\x04': 'Defective Tube Sensor - The changer hasdetected one of the tube sensors behaving abnormally',
          '\x05': 'Double Arrival - Two coins were detected too close together to validate either one',
          '\x06': 'Acceptor Unplugged - The changer has detected that the acceptor has been removed',
          '\x07': 'Tube Jam - A tube payout attempt has resulted in jammed condition',
          '\x08': 'ROM checksum error - The changers internal checksum does not match the calculated checksum',
          '\x09': 'Coin Routing Error - A coin has been validated, but did not follow the intended routing',
          '\x0A': 'Changer Busy - The changer is busy and can not answer a detailed command right now',
          '\x0B': 'Changer was Reset - The changer has detected an Reset condition and has returned to its power-on idle condition',
          '\x0C': 'Coin Jam - A coin(s) has jammed in the acceptance path',
          '\x0D': 'Possible Credited Coin Removal - There has been an attempt to remove a credited coin',
        }.get(answer[i])
        print "IN: " + message
      elif '\x20' <= answer[i] <= '\x3F':
        print "IN: Slugs deposited: " + str(int(self._getbits(answer[i])[3:], 2))
      elif '\x40' <= answer[i] <= '\x7F':
        bits = self._getbits(answer[i])

        if bits[2:4] == '00':
          routing = "Cash Box"
        elif bits[2:4] == '01':
          routing = "Tubes"
        elif bits[2:4] == '10':
          routing = "Not used"
        elif bits[2:4] == '11':
          routing = "Rejected"
        else:
          routing = "Unknown"

        cointype = int(bits[4:8], 2)
        coinsinroutingpath = str(int(self._getbits(answer[i+1]), 2))

        print "IN: Coin deposited: Type " + str(cointype) + ", sent to " + routing  + ". Now " + coinsinroutingpath + " coins there"
        self.__deposited += self.__coins[cointype] * self.__scaling
        i += 1
        break;
      elif '\x80' <= answer[i] <= '\xFE':
        bits = self._getbits(answer[i])
        
        number = str(int(bits[1:4], 2))
        cointype = str(int(bits[4:8], 2))
        coinsintube = str(int(self._getbits(answer[i+1]), 2))
        print "IN: Coins dispensed manually: " + number + " coins of type " + cointype  + ". Now " + coinsintube + " coins there"
        i += 1
        break;
      else: #\x0E -> \x1F
        print "IN: Unknown Poll Status reply" + hexlify(answer[i])
      i += 1
    self.ack()

  def setup(self):
    print "OUT: Setup"
    answer = self._send(data = ['\x09'])
    if len(answer) == 24:
      print "IN: Changer Feature Level: " + str(ord(answer[0])) + " (" + hex(ord(answer[0])) + ")"
      print "IN: Country/Currency-Code: " + hex(ord(answer[1])) + " " + hex(ord(answer[2]))
      print "IN: Coin Scaling Factor: " + str(ord(answer[3])) + " (" + hex(ord(answer[3])) + ")"
      self.__scaling = int(ord(answer[3]))
      print "IN: Decimal Places: " + str(ord(answer[4])) + " (" + hex(ord(answer[4])) + ")"
      canberoutedtotube = (self._getbits(answer[5]) + self._getbits(answer[6]))[::-1]
      for i in range(7, 23):
        print "IN: Coin Type: " + str(i-7) + ", Value: " + str(ord(answer[i])) + ", Can be routed to tube: " + canberoutedtotube[i-7]
        self.__coins[(i-7)] = int(ord(answer[i]))
      self.ack()
    else:
      print "IN: Fail - " + answer

  def expansionidentification(self):
    print "OUT: Expansion Identification"
    answer = self._send(data = ['\x0F', '\x00'])
    if len(answer) == 34:
      print "IN: Manufacturer Code: " + str(answer[0]) + str(answer[1]) + str(answer[2]) + " (" + hex(ord(answer[0])) + " " + hex(ord(answer[1])) + " " + hex(ord(answer[2])) + ")"
      print "IN: Serial Number: " + ''.join(answer[i] for i in range(3, 15)) + " (" + " ".join(hex(ord(answer[i])) for i in range(3, 15)) + ")"
      print "IN: Model #/Tuning Revision: " + ''.join(answer[i] for i in range(15, 27)) + " (" + " ".join(hex(ord(answer[i])) for i in range(15, 27)) + ")"
      print "IN: Software Version: " + hex(ord(answer[27])) + " " + hex(ord(answer[28]))
      optionalfeatures = (self._getbits(answer[29]) + self._getbits(answer[30]) + self._getbits(answer[31]) + self._getbits(answer[32]))[::-1]
      print "IN: Optional Feature: Alternative Payout method: " + optionalfeatures[0]
      print "IN: Optional Feature: Extended Diagnostic command supported: " + optionalfeatures[1]
      print "IN: Optional Feature: Controlled Manual Fill and Payout commands supported: " + optionalfeatures[2]
      print "IN: Optional Feature: File Transport Layer (FTL) supported: " + optionalfeatures[3]
      print "IN: Optional Features: Future extensions: " + optionalfeatures[4:]
      self.ack()
      features = []
      for i in range (29, 33):
        features.append(ord(answer[i]))
      return features
    else:
      print "IN: Fail - " + answer

  def expansionfeatureenable(self, features):
    print "OUT: Expansion Feature Enable"
    answer = self._send(data = ['\x0F', '\x01'] + features)
    if (len(answer) == 1) and (answer[0] == '\x00'):
      print "IN : OK"
      self.ack()
    else:
     print "IN: Fail - " + answer

  def expansiondiagnosticstatus(self):
    print "OUT: Expansion Diagnostic Status"
    answer = self._send(data = ['\x0F', '\x05'])
    if len(answer) == 3:
      print "IN: Main-Code: " + hex(ord(answer[0]))
      print "IN: Sub-Code: " + hex(ord(answer[1]))
      message = {
        '\x01': 'Powering up',
        '\x02': 'Powering down',
        '\x03': 'OK',
        '\x04': 'Keypad shifted',
        '\x05': '',
        '\x06': 'Inhibited by VMC',
        '\x10': '',
        '\x11': '',
        '\x12': '',
        '\x13': '',
        '\x14': '',
        '\x15': '',
        'unknown': 'Unknown Main-Code',
      }.get(answer[0], 'unknown')

      if ( (answer[0] == '\x05') and (answer[1] == '\x10') ):
        message = "Manual Fill / Payout active"

      if ( (answer[0] == '\x05') and (answer[1] == '\x20') ):
        message = "New Inventory Information Available"

      if answer[0] == '\x10':
        message = "General changer error: " + {
          '\x00': 'Non specific error',
          '\x01': 'Check sum error #1. A check sum error over a particular data range of configuration field detected.',
          '\x02': 'Check sum error #2. A check sum error over a secondary data range or configuration field detected.',
          '\x03': 'Low line voltage detected. The changer has disabled acceptance or payout due to a low voltage condition',
          'unknown': 'Unknown Sub-Code',
        }.get(answer[1], 'unknown')

      if answer[0] == '\x11':
        message = "Discriminator module error: " + {
          '\x00': 'Non specific discriminator error.',
          '\x10': 'Flight deck open.',
          '\x11': 'Escrow Return stuck open.',
          '\x30': 'Coin jam in sensor.',
          '\x41': 'Discrimination below specified standard.',
          '\x50': 'Validation sensor A out of range. The acceptor detects a problem with sensor A.',
          '\x51': 'Validation sensor B out of range. The acceptor detects a problem with sensor B.',
          '\x52': 'Validation sensor C out of range. The acceptor detects a problem with sensor C.',
          '\x53': 'Operating temperature exceeded. The acceptor detects the ambient temperature has exceeded the changer\'s operating range, thus possibly affecting the acceptance rate.',
          '\x54': 'Sizing optics failure. The acceptor detects an error in the sizing optics.',
          'unknown': 'Unknown Sub-Code',
      }.get(answer[1], 'unknown')

      if answer[0] == '\x12':
        message = "Accept gate module error: " + {
          '\x00': 'Non specific accept gate error',
          '\x30': 'Coins entered gate, but did not exit.',
          '\x31': 'Accept gate alarm active.',
          '\x40': 'Accept gate open, but no coin detected.',
          '\x50': 'Post gate sensor covered before gate opened.',
          'unknown': 'Unknown Sub-Code',
      }.get(answer[1], 'unknown')

      if answer[0] == '\x13':
        message = "Separator module error: " + {
          '\x00': 'Non specific separator error',
          '\x10': 'Sort sensor error. The acceptor detects an error in the sorting sensor',
          'unknown': 'Unknown Sub-Code',
      }.get(answer[1], 'unknown')

      if answer[0] == '\x14':
        message = "Dispenser module error: " + {
          '\x00': 'Non specific dispenser error.',
          'unknown': 'Unknown Sub-Code',
      }.get(answer[1], 'unknown')

      if answer[0] == '\x15':
        message = "Coin Cassette / tube module error: " + {
          '\x00': 'Non specific cassette error.',
          '\x02': 'Cassette removed.',
          '\x03': 'Cash box sensor error. The changer detects an error in a cash box sensor.',
          '\x04': 'Sunlight on tube sensors. The changer detects too much ambient light on one or more of the tube sensors.',
          'unknown': 'Unknown Sub-Code',
      }.get(answer[1], 'unknown')

      print "IN: Message: " + message
      self.ack()
    else:
      print "IN: Fail - " + answer

  def tubestatus(self):
    print "OUT: Tube Status"
    answer = self._send(data = ['\x0A'])
    if len(answer) == 19:
      print "IN: Tube Full Status: " + hex(ord(answer[0])) + " " + hex(ord(answer[1]))
      for i in range(2, 18):
        print "IN: Tube Status: " + str(i-2) + " --> " + str(ord(answer[i])) + " (" + hex(ord(answer[i])) + ")"
      self.ack()
    else:
      print "IN: Fail - " + answer

  def enableall(self, manual = False):
    if manual == True:
      self.cointype('\xFF', '\xFF', '\xFF', '\xFF')
    else:
      self.cointype('\xFF', '\xFF', '\x00', '\x00')

  def disableall(self, manual = False):
    if manual == True:
      self.cointype('\x00', '\x00', '\xFF', '\xFF')
    else:
      self.cointype('\x00', '\x00', '\x00', '\x00')

  def cointype(self, enable1, enable2, manual1, manual2):
    print "OUT: Coin type"
    answer = self._send(data = ['\x0C', enable1, enable2, manual1, manual2])
    if (len(answer) == 1) and (answer[0] == '\x00'):
      print "IN : OK"
      self.ack()
    else:
      print "IN: Fail - " + answer

  def ack(self):
    print "OUT: ACK"
    # ACK, NACK and RET don't take the mode-Bit
    self._ftdisend('\x00', 0)

  def payout(self, value):
    print "OUT: Payout"
    self._send(data = ['\x0F', '\x02', unhexlify('{:02x}'.format(int(value) / self.__scaling)) ])

  def payoutpoll(self):
    print "OUT: Payout Poll"
    self._send(data = ['\x0F', '\x04'])

  def payoutstatus(self):
    print "OUT: Payout Status"
    self._send(data = ['\x0F', '\x03'])

  def getdeposited(self):
    return self.__deposited

  def cleardeposited(self):
    self.__deposited = 0
Ejemplo n.º 44
0
# Steve Phillips / elimisteve
# 2011.05.11

from pylibftdi import Device
import asterisk.manager, binascii, time
#'\x01\xe7\x6e'
USER_DATA = {
    '\x01\xe7l\x02': {'nick': 'swiss',       'song': 'custom/youngbuk2'},
    '\x01\xe7_Y':    {'nick': 'Joule_Thief', 'song': 'custom/smokeonwater'},
    '\x01\xe7ma':    {'nick': 'elimisteve',  'song': 'custom/loop'},
    '\x01\xe7f\x8d': {'nick': 'luckyaba',    'song': 'custom/goodfoot'}
}

KEY_LENGTH = 6

dev = Device(mode='b')
dev.baudrate = 9600
while True:
    string = dev.read(KEY_LENGTH).strip()
    old_string = '' # Not yet used to compare string and old_string

    if string != "":
        if string in USER_DATA:
            print "Hex:", binascii.b2a_hex(string)
            dev.write('U')

            # Play ringtone/theme song
            manager = asterisk.manager.Manager()
            manager.connect('192.168.1.200')
            manager.login('steve', 'amp111')
Ejemplo n.º 45
0
 def __init__(self, *o, **k):
     Device.__init__(self, *o, **k)
     self.baudrate = 31250
Ejemplo n.º 46
0
#! /usr/bin/python

import sys, os
import time
import random

from pylibftdi import Driver, Device

dev_list = Driver().list_devices()
if len(dev_list) != 0:
    print "Following devices found:"
for device_ in dev_list:
    print device_

dev = Device(device_id="FTZ17IRO", mode='b', interface_select=2)
dev.open()

epochs = 1024 * 10
BLOCK_LEN = 2048
tx_data = bytearray([random.randrange(0, 256) for i in range(BLOCK_LEN)])
ts = time.time()
while epochs:

    dev.write(tx_data)
    rx_data = bytearray(dev.read(BLOCK_LEN))

    #print "Epoch: {}".format(epochs)
    failed = False
    for i in range(BLOCK_LEN):
        if ((tx_data[i] + 1) % 256) != rx_data[i]:
            print "Epoch: {}".format(epochs)
Ejemplo n.º 47
0
"""
    Script to test serial devices
"""

from pylibftdi import Device, Driver, INTERFACE_B

#print Driver().list_devices()
with Device(mode='t', interface_select=INTERFACE_B) as dev:
    dev.baudrate = 115200

    # Send a read command to the board
    dev.write('R 0 4\r\n')

    result = ""
    while 1:
        # This is a non-blocking read (!!!)
        result += dev.read(1)
        print(repr(result))