From 79b7b41c0d981b9c564651f62072b717626fb833 Mon Sep 17 00:00:00 2001 From: Jonathan Hogg Date: Wed, 19 Oct 2016 17:33:11 +0100 Subject: [PATCH] Scaling (with calibration) and triggering working --- .gitignore | 1 + VM registers.xlsx | Bin 36055 -> 36027 bytes scope.py | 126 +++++++++++++++++++++++++++++++++------------- vm.py | 15 ++++-- 4 files changed, 101 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index ee8335b..1cfe9f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +.DS_Store .*.swp __pycache__/ diff --git a/VM registers.xlsx b/VM registers.xlsx index c4dbf42a7206e7760d9e4d8d89937b9c76e24d86..0134a2957ad5c20f6c89ecf21c97bb5787e20811 100644 GIT binary patch delta 6422 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 Jr;-26{|~s!Ne2J` delta 6423 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'.format(nsamples), data)] + if raw: + trace = [(value / 65536 + 0.5) for value in struct.unpack('>{}h'.format(nsamples), data)] + else: + trace = [(value / 65536 + 0.5) * (high - low) + low for value in struct.unpack('>{}h'.format(nsamples), data)] else: - trace = [value / 256 * (high - low) + low for value in data] + if raw: + trace = [value / 256 for value in data] + else: + trace = [value / 256 * (high - low) + low for value in data] traces[channel] = trace return traces @@ -181,10 +207,9 @@ class Scope(vm.VirtualMachine): if not possible_params: raise ValueError("No solution to required frequency/min_samples/max_error") size, nwaves, clock, actualf = sorted(possible_params)[-1][1] - print(len(possible_params), size, nwaves, clock, actualf) async with self.transaction(): if wavetable is None: - mode = {'sine': 0, 'sawtooth': 1, 'exponential': 2, 'square': 3}[waveform.lower()] + mode = {'sine': 0, 'triangle': 1, 'sawtooth': 1, 'exponential': 2, 'square': 3}[waveform.lower()] await self.set_registers(Cmd=0, Mode=mode, Ratio=ratio) await self.issue_synthesize_wavetable() else: @@ -230,22 +255,51 @@ class Scope(vm.VirtualMachine): await self.issue_write_eeprom() return int((await self.read_replies(2))[1], 16) + async def calibrate(self, channels='AB', n=40): + import numpy as np + import pandas as pd + from scipy.optimize import leastsq + await self.start_generator(1000, waveform='square') + items = [] + for low in np.linspace(0.063, 0.4, n): + for high in np.linspace(0.877, 0.6, n): + data = await self.capture(channels=channels, period=1e-3, trigger_level=0.5, nsamples=1000, low=low, high=high, raw=True) + values = np.hstack(list(data.values())) + values.sort() + zero = values[10:len(values)//2-10].mean() + v33 = values[-len(values)//2+10:-10].mean() + analog_range = 3.3 / (v33 - zero) + analog_low = -zero * analog_range + analog_high = analog_low + analog_range + items.append({'low': low, 'high': high, 'analog_low': analog_low, 'analog_high': analog_high}) + data = pd.DataFrame(items) + analog_low_ks, success1 = leastsq(lambda ks, low, high, y: y - self._analog_map_func(ks, low, high), self.analog_low_ks, + args=(data.analog_low, data.analog_high, data.low)) + if success1: + self.analog_low_ks = tuple(analog_low_ks) + analog_high_ks, success2 = leastsq(lambda ks, low, high, y: y - self._analog_map_func(ks, low, high), self.analog_high_ks, + args=(data.analog_low, data.analog_high, data.high)) + if success2: + self.analog_high_ks = tuple(analog_high_ks) + await self.stop_generator() + return success1 and success2 +import numpy as np +import pandas as pd + async def main(): - import numpy as np global s, x, y, data s = await Scope.connect() x = np.linspace(0, 2*np.pi, s.awg_wavetable_size, endpoint=False) y = np.round((np.sin(x)**5)*127 + 128, 0).astype('uint8') - print(await s.start_generator(5000, wavetable=y)) - #print(await s.start_generator(10000, waveform='square', vpp=3, offset=-0.15)) + await s.start_generator(1000, wavetable=y) + #if await s.calibrate(): + # await s.save_params() def capture(*args, **kwargs): - import pandas as pd return pd.DataFrame(asyncio.get_event_loop().run_until_complete(s.capture(*args, **kwargs))) - if __name__ == '__main__': asyncio.get_event_loop().run_until_complete(main()) diff --git a/vm.py b/vm.py index 72c2e36..ad459c5 100644 --- a/vm.py +++ b/vm.py @@ -1,18 +1,21 @@ import asyncio -import numpy as np +import logging import struct +Log = logging.getLogger('streams') + + Registers = { "TriggerLogic": (0x05, 'U8', "Trigger Logic, one bit per channel (0 => Low, 1 => High)"), "TriggerMask": (0x06, 'U8', "Trigger Mask, one bit per channel (0 => Don’t Care, 1 => Active)"), "SpockOption": (0x07, 'U8', "Spock Option Register (see bit definition table for details)"), "SampleAddress": (0x08, 'U24', "Sample address (write) 24 bit"), "SampleCounter": (0x0b, 'U24', "Sample address (read) 24 bit"), - "TriggerIntro": (0x32, 'U24', "Edge trigger intro filter counter (samples/2)"), + "TriggerIntro": (0x32, 'U16', "Edge trigger intro filter counter (samples/2)"), "TriggerOutro": (0x34, 'U16', "Edge trigger outro filter counter (samples/2)"), - "TriggerValue": (0x44, 'S16', "Digital (comparator) trigger (signed)"), + "TriggerValue": (0x44, 'S0.16', "Digital (comparator) trigger (signed)"), "TriggerTime": (0x40, 'U32', "Stopwatch trigger time (ticks)"), "ClockTicks": (0x2e, 'U16', "Master Sample (clock) period (ticks)"), "ClockScale": (0x14, 'U16', "Clock divide by N (low byte)"), @@ -62,7 +65,7 @@ Registers = { "EepromAddress": (0x11, 'U8', "EE Address Register"), "ConverterLo": (0x64, 'U0.16', "VRB ADC Range Bottom (D Trace Mode)"), "ConverterHi": (0x66, 'U0.16', "VRB ADC Range Top (D Trace Mode)"), - "TriggerLevel": (0x68, 'U16', "Trigger Level (comparator, unsigned)"), + "TriggerLevel": (0x68, 'U0.16', "Trigger Level (comparator, unsigned)"), "LogicControl": (0x74, 'U8', "Logic Control"), "Rest": (0x78, 'U16', "DAC (rest) level"), "KitchenSinkA": (0x7b, 'U8', "Kitchen Sink Register A"), @@ -229,7 +232,9 @@ class VirtualMachine: r0 = r1 = None for base, name in sorted((Registers[name][0], name) for name in kwargs): base, dtype, desc = Registers[name] - for i, byte in enumerate(encode(kwargs[name], dtype)): + bs = encode(kwargs[name], dtype) + Log.debug("{} = 0x{}".format(name, ''.join('{:02x}'.format(b) for b in reversed(bs)))) + for i, byte in enumerate(bs): if cmd: cmd += 'z' r1 += 1