def _open_port(device, baudrate, logfile=False, debug=False): """Open the serial communication port""" # the following import enables serial protocol extensions try: if logfile: port = serialext.serial_for_url(device, do_not_open=True) basecls = port.__class__ from pyftdi.serialext.logger import SerialLogger cls = type('Spy%s' % basecls.__name__, (SerialLogger, basecls), {}) port = cls(device, baudrate=baudrate, timeout=0, logfile=logfile) else: port = serialext.serial_for_url(device, baudrate=baudrate, timeout=0, do_not_open=True) port.open() if not port.is_open: raise IOError('Cannot open port "%s"' % device) if debug: print("Using serial backend '%s'" % port.BACKEND) return port except IOError as ex: # SerialException derives from IOError raise
def test_uart_cross_talk_sp(self): something_out = self.generate_bytes() """Exchange a random byte stream between the two first UART interfaces of the same FTDI device, from the same process This also validates PyFtdi support to use several interfaces on the same FTDI device from the same Python process """ urla = URL urlb = self.build_next_url(urla) porta = serial_for_url(urla, baudrate=1000000) portb = serial_for_url(urlb, baudrate=1000000) try: if not porta.is_open: porta.open() if not portb.is_open: portb.open() # print("porta: %d:%d:%d" % porta.usb_path) # print("portb: %d:%d:%d" % portb.usb_path) porta.timeout = 1.0 portb.timeout = 1.0 something_out = self.generate_bytes() porta.write(something_out) something_in = portb.read(len(something_out)) self.assertEqual(len(something_in), len(something_out)) self.assertEqual(something_in, something_out) something_out = self.generate_bytes() portb.write(something_out) something_in = porta.read(len(something_out)) self.assertEqual(len(something_in), len(something_out)) self.assertEqual(something_in, something_out) finally: porta.close() portb.close()
def test2_uart_cross_talk_speed(self): urla = URL urlb = self.build_next_url(urla) porta = serial_for_url(urla, baudrate=6000000) portb = serial_for_url(urlb, baudrate=6000000) size = int(1e6) results = [None, None] chunk = 537 source = Thread(target=self._stream_source, args=(porta, chunk, size, results), daemon=True) sink = Thread(target=self._stream_sink, args=(portb, size, results), daemon=True) sink.start() source.start() source.join() sleep(0.5) sink.join() if isinstance(results[1], Exception): raise results[1] tsize, tdelta = results[0] rsize, rdelta = results[1] self.assertGreater(rsize, 0, 'Not data received') if self.debug: print(f'TX: {tsize} bytes, {tdelta*1000:.3f} ms, ' f'{int(8*tsize/tdelta):d} bps') print(f'RX: {rsize} bytes, {rdelta*1000:.3f} ms, ' f'{int(8*rsize/rdelta):d} bps') self.assertTrue(rsize >= tsize - 4 * chunk, 'Data loss')
def test_loopback_talk_speed(self): port = serial_for_url(URL, baudrate=6000000) size = int(1e6) results = [None, None] chunk = 537 source = Thread(target=self._stream_source, args=(port, chunk, size, results), daemon=True) sink = Thread(target=self._stream_sink, args=(port, size, results), daemon=True) sink.start() source.start() source.join() sleep(0.5) sink.join() if isinstance(results[1], Exception): #pylint: disable-msg=raising-bad-type raise results[1] #pylint: disable-msg=unpacking-non-sequence tsize, tdelta = results[0] rsize, rdelta = results[1] self.assertGreater(rsize, 0, 'Not data received') if self.debug: print(f'TX: {tsize} bytes, {tdelta*1000:.3f} ms, ' f'{int(8*tsize/tdelta):d} bps') print(f'RX: {rsize} bytes, {rdelta*1000:.3f} ms, ' f'{int(8*rsize/rdelta):d} bps') self.assertTrue(rsize >= tsize - 4 * chunk, 'Data loss')
def _cross_talk_read_then_write(self, url, refstream): port = serial_for_url(url, baudrate=1000000) try: if not port.is_open: port.open() port.timeout = 5.0 instream = port.read(len(refstream)) self.assertEqual(len(instream), len(refstream)) self.assertEqual(instream, refstream) # the peer expect us to return the same stream, inverted outstream = bytes(reversed(instream)) port.write(outstream) finally: port.close()
def test(self): """Check simple TX/RX sequence.""" port = serial_for_url('ftdi:///1') bus, address, _ = port.usb_path vftdi = self.loader.get_virtual_ftdi(bus, address) msg = ascii_letters port.write(msg.encode()) buf = vftdi.uart_read(len(ascii_letters) + 10).decode() self.assertEqual(msg, buf) msg = ''.join(reversed(msg)) vftdi.uart_write(msg.encode()) buf = port.read(len(ascii_letters)).decode() self.assertEqual(msg, buf) port.close()
def test_uart_loopback(self): """Check TXD/RXD loopback.""" with open('pyftdi/tests/resources/ft232h.yaml', 'rb') as yfp: self.loader.load(yfp) port = serial_for_url('ftdi:///1') bus, address, _ = port.usb_path vftdi = self.loader.get_virtual_ftdi(bus, address) vport = vftdi.get_port(1) txd = vport[vport.UART_PINS.TXD] rxd = vport[vport.UART_PINS.RXD] txd.connect_to(rxd) msg = ascii_letters port.write(msg.encode()) buf = port.read(len(ascii_letters)).decode() self.assertEqual(msg, buf) port.close()
def test_baudrate_hs_dev(self): """Check baudrate settings for high speed devices.""" with open('pyftdi/tests/resources/ft232h.yaml', 'rb') as yfp: self.loader.load(yfp) port = serial_for_url('ftdi:///1', baudrate=1200) bus, address, _ = port.usb_path vftdi = self.loader.get_virtual_ftdi(bus, address) vport = vftdi.get_port(1) self.assertRaises(ValueError, setattr, port, 'baudrate', 100) self.assertRaises(ValueError, setattr, port, 'baudrate', 12100000) for baudrate in (200, 600, 1200, 2400, 4800, 9600, 115200, 230400, 460800, 490000, 921600, 1000000, 1200000, 1500000, 2000000, 3000000, 4000000, 6000000): port.baudrate = baudrate #print(f'{baudrate} -> {port.ftdi.baudrate} -> {vport.baudrate}') self.assertEqual(port.ftdi.baudrate, vport.baudrate) port.close()
def connect_over_serial(url, baudrate): from term import getkey from sys import platform, stdin, stdout, stderr MSWIN = platform == 'win32' if not MSWIN: from termios import TCSANOW, tcgetattr, tcsetattr if not MSWIN and stdout.isatty(): termstates = [(fd, tcgetattr(fd)) for fd in (stdin.fileno(), stdout.fileno(), stderr.fileno())] from pyftdi.serialext import serial_for_url try: port = serial_for_url(url, baudrate=baudrate) except SerialException as e: print("Uh-oh:", e) from pyftdi.ftdi import Ftdi Ftdi().open_from_url('ftdi:///?') sys.exit(1) print("Connected.") try: while True: try: c = getkey(False) if MSWIN and ord(c) == 3: raise KeyboardInterrupt() stdout.write(c.decode('utf8', errors='replace')) stdout.flush() port.write(c) except KeyboardInterrupt: port.close() print("kbai") break finally: for fd, att in termstates: tcsetattr(fd, TCSANOW, att)
def test_uart(self): """Check simple TX/RX sequence.""" with open('pyftdi/tests/resources/ft232h.yaml', 'rb') as yfp: self.loader.load(yfp) port = serial_for_url('ftdi:///1') bus, address, _ = port.usb_path vftdi = self.loader.get_virtual_ftdi(bus, address) vport = vftdi.get_port(1) msg = ascii_letters port.write(msg.encode()) txd = vport[vport.UART_PINS.TXD] buf = txd.read(len(ascii_letters) + 10).decode() self.assertEqual(msg, buf) msg = ''.join(reversed(msg)) rxd = vport[vport.UART_PINS.TXD] rxd.write(msg.encode()) buf = port.read(len(ascii_letters)).decode() self.assertEqual(msg, buf) port.close()
def _cross_talk_read_then_write(cls, url, refstream): # use classmethod & direct AssertionError to avoid pickler issues # with multiprocessing: # "TypeError: cannot serialize '_io.TextIOWrapper' object" port = serial_for_url(url, baudrate=1000000) try: if not port.is_open: port.open() port.timeout = 5.0 instream = port.read(len(refstream)) if len(instream) != len(refstream): raise AssertionError('Stream length differ') if instream != refstream: raise AssertionError('Stream content differ') # the peer expect us to return the same stream, inverted outstream = bytes(reversed(instream)) port.write(outstream) finally: port.close()
def test_uart_loopback(self): something_out = self.generate_bytes() """Exchange a random byte stream between the two first UART interfaces of the same FTDI device, from the same process This also validates PyFtdi support to use several interfaces on the same FTDI device from the same Python process """ port = serial_for_url(URL, baudrate=1000000) for _ in range(10): try: if not port.is_open: port.open() port.timeout = 1.0 something_out = self.generate_bytes() port.write(something_out) something_in = port.read(len(something_out)) self.assertEqual(len(something_in), len(something_out)) self.assertEqual(something_in, something_out) finally: port.close()
def test_uart_loopback(self): something_out = self.generate_bytes() """Exchange a random byte stream between the two first UART interfaces of the same FTDI device, from the same process This also validates PyFtdi support to use several interfaces on the same FTDI device from the same Python process """ port = serial_for_url(URL, baudrate=1000000) for cycle in range(10): try: if not port.is_open: port.open() port.timeout = 1.0 something_out = self.generate_bytes() port.write(something_out) something_in = port.read(len(something_out)) print(len(something_in)) self.assertEqual(len(something_in), len(something_out)) self.assertEqual(something_in, something_out) finally: print("close") port.close()
#!/usr/bin/env python3 from binascii import hexlify import sys import pyftdi.serialext as ftdi import parse ser = ftdi.serial_for_url('ftdi:///2', baudrate=12000000) while True: line = ser.readline().rstrip() lpc = parse.parse_line(line) if not lpc: continue lpctype, direction, address, data = lpc print('%3s: %5s %8s: %4s' % (lpctype, direction, address, data))
original_read = ser.read def new_read(*args, **kwargs): ret_val = original_read(*args, **kwargs) if isinstance(ret_val, bytearray): return bytes(ret_val) else: return ret_val ser.read = new_read my_ftdi_url = 'ftdi:///1' baud_rate = 115200 timeout = 5 ser = serial_for_url(my_ftdi_url, baud_rate) pyftdi_readline_fix(ser) ser.write(b'at\r\n') time.sleep(.3) line1 = ser.readline() print(line1.decode("utf-8")) ser.write(b'AT+CSQ\r\n') time.sleep(.3) line2 = ser.readline() print(line2.decode("utf-8")) print('finished')