Skip to content

Commit c154108

Browse files
committed
Add PrawnDO docs
1 parent ce147e9 commit c154108

File tree

2 files changed

+212
-0
lines changed

2 files changed

+212
-0
lines changed

docs/source/devices.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Many pseudoclock devices also include other types of outputs, including digital
1919
devices/opalkellyXEM3001
2020
devices/pineblaster
2121
devices/prawnblaster
22+
devices/prawndo
2223
devices/rfblaster
2324

2425
NI DAQS

docs/source/devices/prawndo.rst

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
PrawnDO
2+
=======
3+
4+
This labscript device controls the `PrawnDO <https://github.com/labscript-suite/prawn_digital_output>`_
5+
open-source digital output generator based on the
6+
`Raspberry Pi Pico <https://www.raspberrypi.org/documentation/rp2040/getting-started/>`_ platform.
7+
It is designed to be a companion device to the :doc:`PrawnBlaster <prawnblaster>` allowing for
8+
arbitrary digital output specification (in contrast to the variable pseudoclock generation of the PrawnBlaster).
9+
10+
Initial code development was in this `repository <https://github.com/pmiller2022/prawn_digital_output_labscript>`_.
11+
12+
Specifications
13+
~~~~~~~~~~~~~~
14+
15+
The PrawnDO takes advantage of the specs of the Pico to provide the following:
16+
17+
* 16 synchronous digital outputs with timing specs equivalent to the PrawnBlaster
18+
19+
- Timing resolution for an update is 1 clock cycle (10 ns at default 100 MHz clock)
20+
- Minimum time between updates (on any output) is 5 clock cycles (50 ns with 100 MHz clock)
21+
- Maximum time between updates (on any output) is 2^32-1 clock cycles (~42.9 s with 100 MHz clock)
22+
- Updates are internally timed (ie only initial triggering is needed, not for every update)
23+
24+
* 30,000 instructions (where each instruction can be held between 5 and 2^32-1 clock cycles)
25+
* Support for external hardware triggers to begin and re-start execution after a wait.
26+
* Can be referenced to an external LVCMOS clock
27+
* Internal clock can be set up to 133 MHz (which scales timing specs accordingly)
28+
29+
30+
Installation
31+
~~~~~~~~~~~~
32+
33+
In order to turn the standard Pico into a PrawnDO, you need to load the custom firmware
34+
available in the `Github repo <https://github.com/labscript-suite/prawn_digital_output/releases>`_ onto the board.
35+
The simplest way to do this is by holding the reset button on the board while plugging the USB into a computer.
36+
This will bring up a mounted folder that you copy-paste the firmware to.
37+
Once copied, the board will reset and be ready to go.
38+
39+
Note that this device communicates using a virtual COM port.
40+
The number is assigned by the controlling computer and will need to be determined in order for BLACS to connect to the PrawnDO.
41+
42+
43+
Usage
44+
~~~~~
45+
46+
The pinout for the PrawnDO is as follows:
47+
48+
* Outputs 0-15 (labelled by default in hex 0-F): GPIO pins 0-15, respectively.
49+
* External Trigger input: GPIO 16
50+
* External Clock input: GPIO 20
51+
52+
Note that signal cables should be connected to the Pico digital grounds for proper operation.
53+
54+
The PrawnDO can provide up to 16 digital outputs, which are accessed via `name.outputs`.
55+
Each channel is specified using the corresponding hex character (spanning 0-F for 0-15).
56+
The channel string must end with a single character between 0-F to be valid
57+
(i.e. `'flag 0'`, `'do 0'`, and `'0'` are all valid channel specifications for GPIO 0 of the PrawnDO).
58+
59+
An example connection table that uses the PrawnBlaster and PrawnDO:
60+
61+
.. code-block:: python
62+
63+
from labscript import *
64+
65+
from labscript_devices.PrawnBlaster.labscript_devices import PrawnBlaster
66+
from labscript_devices.PrawnDO.labscript_devices import PrawnDO
67+
68+
PrawnBlaster(name='prawn', com_port='COM6', num_pseudoclocks=1)
69+
70+
PrawnDO(name='prawn_do', com_port='COM5', clock_line=prawn.clocklines[0])
71+
72+
DigitalOut('do0', prawn_do.outputs, 'flag 0')
73+
DigitalOut('do1', prawn_do.outputs, 'chan 1')
74+
DigitalOut('do10', prawn_do.outputs, 'flag C')
75+
76+
if __name__ == "__main__":
77+
78+
start()
79+
80+
stop(1)
81+
82+
.. note::
83+
84+
The PrawnDO is designed to be directly connected to a Clockline,
85+
something not normally done for internally-timed devices in labscript.
86+
This is merely for simplicity under the most typical use case of
87+
adding standard digital output capability to a PrawnBlaster master pseudoclocking device.
88+
89+
When used in this way, the PrawnDO can share the Clockline with other devices,
90+
especially with other PrawnDO boards allowing for significant fan-out.
91+
Nominally, the PrawnDO will ignore clock ticks from other devices on the same Clockline,
92+
such as a DAQ.
93+
However, standard cautions should be taken when sharing a clockline between devices
94+
(i.e. don't overload the physical output driver with too many parallel devices,
95+
limit the number of devices doing fast things at nearly the same times,
96+
validate critical timings/operations independently).
97+
98+
The PrawnDO can also be triggerd from a standard DigitalOut Trigger.
99+
In this case, the `clock_line` argument is not used,
100+
but the standard `trigger_device` and `trigger_connection` arguments.
101+
102+
Synchronization
103+
---------------
104+
105+
The PrawnDO generates output based on internal timing with external starting triggers
106+
in a manner nearly equivalent to the PrawnBlaster.
107+
This means that under a typical use case of a PrawnBlaster used with a PrawnDO,
108+
the output timings of the devices will drift as their internal clocks drift.
109+
Each Pico is specified to have a clock with better than 50 ppm stability,
110+
meaning drift could be as bad as 100 ppm between two devices
111+
(e.g. 100 microsecond drift after 1 second of run time).
112+
In practice, relative drift is often around 5 ppm.
113+
114+
To overcome this, either use labscript waits right before time-sensitive operations
115+
to resynchronize back to within a single clock cycle (:math:`\pm10` ns),
116+
or use a common external clock for both devices.
117+
118+
Unless buffering/level protecting circuitry is used,
119+
both the PrawnBlaster and the PrawnDO require LVCMOS square-wave clock signals.
120+
An example evaluation board with a flexible, multi-channel LVCMOS clock generator is
121+
the SI535X-B20QFN-EVB.
122+
Note that interrupting the external clock can cause the Pico serial communication to freeze.
123+
Recovery requires resetting the board via a power cycle or shorting the RUN pin to ground
124+
to re-enable default options including the internal clock.
125+
126+
An example connection table using external clocks with the default frequency of 100 MHz is:
127+
128+
.. code-block:: python
129+
130+
from labscript import *
131+
132+
from labscript_devices.PrawnBlaster.labscript_devices import PrawnBlaster
133+
from labscript_devices.PrawnDO.labscript_devices import PrawnDO
134+
135+
PrawnBlaster(name='prawn', com_port='COM6', num_pseudoclocks=1,
136+
external_clock_pin=20)
137+
138+
PrawnDO(name='prawn_do', com_port='COM5', clock_line=prawn.clocklines[0],
139+
external_clock=True)
140+
141+
DigitalOut('do0', prawn_do.outputs, 'flag 0')
142+
DigitalOut('do1', prawn_do.outputs, 'chan 1')
143+
DigitalOut('do10', prawn_do.outputs, 'flag C')
144+
145+
if __name__ == "__main__":
146+
147+
start()
148+
149+
stop(1)
150+
151+
152+
Input/Output Buffers
153+
--------------------
154+
155+
While the PrawnBlaster and PrawnDO boards can be used as is,
156+
it is often a good idea to add unity-gain channel buffers to the inputs and outputs.
157+
Using buffers and line drivers from a LVCMOS family with 5V/TTL tolerant inputs can provide
158+
compatibility with TTL inputs and drive higher capacitance loads (such a long BNC cables) more reliably.
159+
An example that implements these buffers can be found `here <https://github.com/naqslab/PrawnDO_Breakout_Connectorized>`_.
160+
161+
Waits
162+
-----
163+
164+
All waits in the PrawnDO are indefinite waits in the parlance of the PrawnBlaster.
165+
This means they will never time out, but must have an external trigger to restart execution.
166+
Changing a digital output state concurrently with a wait
167+
results in the PrawnDO output holding the updated value during the wait.
168+
For example, in the following code snippet, the output of `do0` will be low during the wait.
169+
For the output of `do0` to remain high during the wait,
170+
the second instruction (`do0.go_low(t)`) must be at least 5 clock cycles after the wait start time.
171+
172+
.. code-block:: python
173+
174+
t = 0
175+
do.go_high(t)
176+
t = 1e-3
177+
wait('my_wait', t)
178+
do0.go_low(t)
179+
180+
Detailed Documentation
181+
~~~~~~~~~~~~~~~~~~~~~~
182+
183+
.. automodule:: labscript_devices.PrawnDO
184+
:members:
185+
:undoc-members:
186+
:show-inheritance:
187+
:private-members:
188+
189+
.. automodule:: labscript_devices.PrawnDO.labscript_devices
190+
:members:
191+
:undoc-members:
192+
:show-inheritance:
193+
:private-members:
194+
195+
.. automodule:: labscript_devices.PrawnDO.blacs_tabs
196+
:members:
197+
:undoc-members:
198+
:show-inheritance:
199+
:private-members:
200+
201+
.. automodule:: labscript_devices.PrawnDO.blacs_workers
202+
:members:
203+
:undoc-members:
204+
:show-inheritance:
205+
:private-members:
206+
207+
.. automodule:: labscript_devices.PrawnDO.runviewer_parsers
208+
:members:
209+
:undoc-members:
210+
:show-inheritance:
211+
:private-members:

0 commit comments

Comments
 (0)