- Calls to safe OpalKelly.jl bindings to the FrontPanel API
- Plots using Makie
- Save datasets in HDF5 files with date and description annotation
- Update QuantiCam API to support the new FW
If running Nix, just run nix develop and everything will be setup for you.
But if running Linux without nix, you just need to reverse the flake.nix
to setup your env in the same way.
Install the driver required from FrontPanelUSB driver.
Julia needs to be installed and added to the Path.
First we need to add DATASTORE_3D_PATH to point to the 3D_VISION group
datastore, where all the released firmware versions are placed. This API uses
this env variable to search for the fw bitfile.
DATASTORE_3D_PATH=\\csce.ed.ac.uk\csce\eng\groups\3D_VISION
From the terminal, making sure you have Julia in the path, run julia in the
QuantiCam.jl root repository path.
julia >
# Press ] to switch to Pkg mode
(@v1.11) pkg> activate .
(@v1.11) pkg> instantiateThen return to Julia mode pressing backspace
using GLMakie
using QuantiCam
qc = load_qc(config_path="./config/photon_cnt.json")
live_histogram(qc)graph LR;
start-->plot_collector;
start-->hdf5_collector;
start-->config;
config--->setup;
setup--->daq;
daq-->bank_operations;
bank_operations-->daq;
daq-->frame_cast;
daq-->frame_check;
daq--hdf5_channel-->hdf5_collector;
daq--plot_channel-->plot_collector;
frame_cast-->processing;
You can view the datasets by loading the data and display it as you wish, or use dataviewer
The QuantiCam description of the sensor functionality is described in the paper @6AFTWQX9#Henderson_Etal-2019. This shows the SPAD front-end gating for single-photon count (SPC) and time-correlated single-photon count (TCPSC), the pseudo-differential ring oscillator (PRVCO/GRO) implemented with the level-shifters necessary to quantize the TDC fine codes and finally the ripple counter used for coarse TCPSC or generally SPC counting.
The read-out of the sensor is done for each row-pair sequentially through the parrallel-input serial-output interface of the chip (top and bottom rows) which gobble 4 columns together in a PISO line. Therefore there are 32 + 32 PISO lines for top and bottom, each serialising 4 columns of 14 bits each (56 bits).
The coding scheme for the each PISO 14-bits readout is:
| Field |
|
SPADWIN | C0 | C8,1 |
|---|---|---|---|---|
| Bits | 13:10 | 9 | 8 | 7:0 |
Default {$F_3$,$F_2$,$F_1$,$F_2$} when TDC is reset is: 0110, so the received
encoding is {$F_3$,$\overline{F_2}$,$F_1$,$\overline{F_0}$}=0011
[!WARN] The initialized value extracted from the paper doesn't make sense, it should be
1010but it does match with the observed code for untriggered SPADS: 0x04 fine code
The flags enconding from the ring-oscillator for the fine counting are then decoded in unsigned representation:
|
|
Fine decoded | 2's complement | |
|---|---|---|---|
| 1010 | 0000 | 100 | 100 |
| 0010 | 1000 | 011 | 101 |
| 0110 | 1100 | 010 | 110 |
| 0100 | 1110 | 001 | 111 |
| 0101 | 1111 | 000 | 000 |
| 1101 | 0111 | 111 | 001 |
| 1001 | 0011 | 110 | 010 |
| 1011 | 0001 | 101 | 011 |
Proposing new decoding to reflect the monotonicity and not take 2's complement implicit of the decoding to ensure correctness.
|
|
Fine decoded | 2's complement | |
|---|---|---|---|
| 1010 | 0000 | 000 | *000 |
| 0010 | 1000 | 001 | 111 |
| 0110 | 1100 | 010 | 110 |
| 0100 | 1110 | 011 | 101 |
| 0101 | 1111 | 100 | 100 |
| 1101 | 0111 | 101 | 011 |
| 1001 | 0011 | 110 | 010 |
| 1011 | 0001 | 111 | 001 |
The coarse counter is incremented on the falling edge of
This is then converted for the SPC and TCPSC modes with varying encoding based on the byte_mode selected:
- Full readout
- SPC:
15:9 8:0 HEADER[6:0] {C8,1, SPADWIN} - TCSPC:
15:12 11:3 2:0 HEADER[2:0] {C8,1, C0} fine decoded
- SPC:
- Byte select
- SPC:
byte_select_msb 7:0 0 {C7,1, SPADWIN} 1 C8,1 - TCSPC:
7:3 2:0 {C4,1, C0} fine decoded
- SPC:
[!WARN] Measurement as 2's complement inversion seems to happen twice, both on FW and SW side
- Vary delay and observe histogram shifting
- Vary gate_width to observe multiple peaks or only one peak
- Double check that the raw readout for 16-bits mode is interleaved {col4, col3, col2, col1, 0 (FIFO empty)}, then make a strategy to fixup the backpressure on the FIFO
- Check trigger in aggregation that could fixup the 16-bits mode issue
- The FrontPanel API triggers one bit at a time, so this can't be the cause
Duplicate logic from the MATLAB code into Julia, but fix it up eventually by fixing the logic in the FW.
- Extract Vddro-> TDC resolution from the paper in a tabular form; There are tools to visually extract such information from papers, USE ONE. This gives the general trend, but per pixel calibration still needs to be performed.
- Expand the beam and center it on the sensor to produce a uniform time distribution illumination over the sensor region. => Tweak frequencies to result in a uniform peak extraction.
- Calibrate frequency based on different delays used