mirror of
https://github.com/jonathanhogg/scopething
synced 2025-07-14 11:12:09 +01:00
Work in progress
This commit is contained in:
27
scope.py
27
scope.py
@ -23,19 +23,22 @@ class Scope(vm.VirtualMachine):
|
|||||||
scope = cls(streams.SerialStream())
|
scope = cls(streams.SerialStream())
|
||||||
elif os.path.exists(device):
|
elif os.path.exists(device):
|
||||||
scope = cls(streams.SerialStream(device=device))
|
scope = cls(streams.SerialStream(device=device))
|
||||||
|
elif ':' in device:
|
||||||
|
host, port = device.split(':', 1)
|
||||||
|
Log.info("Connecting to remote scope at {}:{}".format(host, port))
|
||||||
|
reader, writer = await asyncio.open_connection(host, int(port))
|
||||||
|
scope = cls(reader, writer)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Don't know what to do with '{}'".format(device))
|
raise ValueError("Don't know what to do with '{}'".format(device))
|
||||||
await scope.setup()
|
await scope.setup()
|
||||||
return scope
|
return scope
|
||||||
|
|
||||||
def __init__(self, stream):
|
|
||||||
super(Scope, self).__init__(stream)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _analog_map_func(ks, low, high):
|
def _analog_map_func(ks, low, high):
|
||||||
return ks[0] + ks[1]*low + ks[2]*high
|
return ks[0] + ks[1]*low + ks[2]*high
|
||||||
|
|
||||||
async def setup(self):
|
async def setup(self):
|
||||||
|
Log.info("Resetting scope")
|
||||||
await self.reset()
|
await self.reset()
|
||||||
await self.issue_get_revision()
|
await self.issue_get_revision()
|
||||||
revision = ((await self.read_replies(2))[1]).decode('ascii')
|
revision = ((await self.read_replies(2))[1]).decode('ascii')
|
||||||
@ -58,6 +61,14 @@ class Scope(vm.VirtualMachine):
|
|||||||
self._generator_running = False
|
self._generator_running = False
|
||||||
Log.info("Initialised scope, revision: {}".format(revision))
|
Log.info("Initialised scope, revision: {}".format(revision))
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self._writer is not None:
|
||||||
|
self._writer.close()
|
||||||
|
self._writer = None
|
||||||
|
self._reader = None
|
||||||
|
|
||||||
|
__del__ = close
|
||||||
|
|
||||||
async def load_params(self):
|
async def load_params(self):
|
||||||
params = []
|
params = []
|
||||||
for i in range(struct.calcsize('<H8fH')):
|
for i in range(struct.calcsize('<H8fH')):
|
||||||
@ -200,7 +211,7 @@ class Scope(vm.VirtualMachine):
|
|||||||
DumpCount=nsamples, DumpRepeat=1, DumpSend=1, DumpSkip=0)
|
DumpCount=nsamples, DumpRepeat=1, DumpSend=1, DumpSkip=0)
|
||||||
await self.issue_program_spock_registers()
|
await self.issue_program_spock_registers()
|
||||||
await self.issue_analog_dump_binary()
|
await self.issue_analog_dump_binary()
|
||||||
data = await self._stream.readexactly(nsamples * sample_width)
|
data = await self._reader.readexactly(nsamples * sample_width)
|
||||||
if sample_width == 2:
|
if sample_width == 2:
|
||||||
if raw:
|
if raw:
|
||||||
trace = [(value / 65536 + 0.5) for value in struct.unpack('>{}h'.format(nsamples), data)]
|
trace = [(value / 65536 + 0.5) for value in struct.unpack('>{}h'.format(nsamples), data)]
|
||||||
@ -323,7 +334,6 @@ class Scope(vm.VirtualMachine):
|
|||||||
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
global s, x, y, data
|
global s, x, y, data
|
||||||
@ -338,10 +348,13 @@ async def main():
|
|||||||
# await s.save_params()
|
# await s.save_params()
|
||||||
|
|
||||||
def capture(*args, **kwargs):
|
def capture(*args, **kwargs):
|
||||||
return pd.DataFrame(asyncio.get_event_loop().run_until_complete(s.capture(*args, **kwargs)))
|
return asyncio.get_event_loop().run_until_complete(s.capture(*args, **kwargs))
|
||||||
|
|
||||||
|
def calibrate(*args, **kwargs):
|
||||||
|
return asyncio.get_event_loop().run_until_complete(s.calibrate(*args, **kwargs))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
#logging.basicConfig(level=logging.DEBUG, stream=sys.stderr)
|
logging.basicConfig(level=logging.DEBUG, stream=sys.stderr)
|
||||||
asyncio.get_event_loop().run_until_complete(main())
|
asyncio.get_event_loop().run_until_complete(main())
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ import asyncio
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import serial
|
import serial
|
||||||
import serial.tools.list_ports
|
|
||||||
|
|
||||||
|
|
||||||
Log = logging.getLogger('streams')
|
Log = logging.getLogger('streams')
|
||||||
@ -11,12 +10,8 @@ Log = logging.getLogger('streams')
|
|||||||
|
|
||||||
class SerialStream:
|
class SerialStream:
|
||||||
|
|
||||||
@staticmethod
|
def __init__(self, device, loop=None, **kwargs):
|
||||||
def available_ports():
|
self._device = device
|
||||||
return [port.device for port in serial.tools.list_ports.comports() if port.usb_description() == 'FT245R USB FIFO']
|
|
||||||
|
|
||||||
def __init__(self, port=0, device=None, loop=None, **kwargs):
|
|
||||||
self._device = self.available_ports()[port] if device is None else device
|
|
||||||
self._connection = serial.Serial(self._device, timeout=0, write_timeout=0, **kwargs)
|
self._connection = serial.Serial(self._device, timeout=0, write_timeout=0, **kwargs)
|
||||||
self._loop = loop if loop is not None else asyncio.get_event_loop()
|
self._loop = loop if loop is not None else asyncio.get_event_loop()
|
||||||
self._input_buffer = bytes()
|
self._input_buffer = bytes()
|
||||||
|
28
vm.py
28
vm.py
@ -194,8 +194,9 @@ class VirtualMachine:
|
|||||||
await self._vm.issue(self._data)
|
await self._vm.issue(self._data)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __init__(self, stream):
|
def __init__(self, reader, writer):
|
||||||
self._stream = stream
|
self._reader = reader
|
||||||
|
self._writer = writer
|
||||||
self._transactions = []
|
self._transactions = []
|
||||||
|
|
||||||
def transaction(self):
|
def transaction(self):
|
||||||
@ -205,26 +206,39 @@ class VirtualMachine:
|
|||||||
if isinstance(cmd, str):
|
if isinstance(cmd, str):
|
||||||
cmd = cmd.encode('ascii')
|
cmd = cmd.encode('ascii')
|
||||||
if not self._transactions:
|
if not self._transactions:
|
||||||
await self._stream.write(cmd)
|
Log.debug("Issue: {}".format(repr(cmd)))
|
||||||
echo = await self._stream.readexactly(len(cmd))
|
self._writer.write(cmd)
|
||||||
|
await self._writer.drain()
|
||||||
|
echo = await self._reader.readexactly(len(cmd))
|
||||||
if echo != cmd:
|
if echo != cmd:
|
||||||
raise RuntimeError("Mismatched response")
|
raise RuntimeError("Mismatched response")
|
||||||
else:
|
else:
|
||||||
self._transactions[-1].append(cmd)
|
self._transactions[-1].append(cmd)
|
||||||
|
|
||||||
|
async def readuntil(self, separator):
|
||||||
|
data = b''
|
||||||
|
while not data.endswith(separator):
|
||||||
|
data += await self._reader.read(1)
|
||||||
|
return data
|
||||||
|
|
||||||
async def read_replies(self, n):
|
async def read_replies(self, n):
|
||||||
if self._transactions:
|
if self._transactions:
|
||||||
raise TypeError("Command transaction in progress")
|
raise TypeError("Command transaction in progress")
|
||||||
replies = []
|
replies = []
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
replies.append((await self._stream.readuntil(b'\r'))[:-1])
|
reply = (await self.readuntil(b'\r'))[:-1]
|
||||||
|
Log.debug("Read reply: {}".format(repr(reply)))
|
||||||
|
replies.append(reply)
|
||||||
return replies
|
return replies
|
||||||
|
|
||||||
async def reset(self):
|
async def reset(self):
|
||||||
if self._transactions:
|
if self._transactions:
|
||||||
raise TypeError("Command transaction in progress")
|
raise TypeError("Command transaction in progress")
|
||||||
await self._stream.write(b'!')
|
Log.debug("Issue reset")
|
||||||
await self._stream.readuntil(b'!')
|
self._writer.write(b'!')
|
||||||
|
await self._writer.drain()
|
||||||
|
await self.readuntil(b'!')
|
||||||
|
Log.debug("Reset complete")
|
||||||
|
|
||||||
async def set_registers(self, **kwargs):
|
async def set_registers(self, **kwargs):
|
||||||
cmd = ''
|
cmd = ''
|
||||||
|
Reference in New Issue
Block a user