Skip to content

Commit

Permalink
Merge pull request #55 from tknopp/nh/sata
Browse files Browse the repository at this point in the history
SATA-based trigger distribution
  • Loading branch information
nHackel authored Mar 20, 2023
2 parents e197c8c + 08f20ac commit 712c003
Show file tree
Hide file tree
Showing 9 changed files with 268 additions and 23 deletions.
40 changes: 39 additions & 1 deletion src/client/julia/src/ADC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export TriggerMode, INTERNAL, EXTERNAL, ADCPerformanceData, RPStatus, Performanc
decimation, decimation!, numChan, samplesPerPeriod, samplesPerPeriod!, periodsPerFrame, periodsPerFrame!,
currentWP, currentPeriod, currentFrame, masterTrigger, masterTrigger!, keepAliveReset, keepAliveReset!,
triggerMode, triggerMode!, startADC, stopADC, overwritten, corrupted, serverStatus, performanceData,
readSamples, startPipelinedData, stopTransmission
readSamples, startPipelinedData, stopTransmission, triggerPropagation, triggerPropagation!

"""
TriggerMode
Expand Down Expand Up @@ -300,6 +300,44 @@ scpiCommand(::typeof(triggerMode)) = "RP:TRIGger:MODe?"
scpiReturn(::typeof(triggerMode)) = TriggerMode
parseReturn(::typeof(triggerMode), ret) = stringToEnum(TriggerMode, strip(ret, '\"'))

"""
triggerPropagation!(rp::RedPitaya, val::Bool)
Set the trigger propagation of the RedPitaya to `val`. Return `true` if the command was successful.
# Example
```julia
julia> triggerPropagation!(rp, true)
true
julia>triggerPropagation(rp)
true
```
"""
function triggerPropagation!(rp::RedPitaya, val)
return query(rp, scpiCommand(triggerPropagation!, val), scpiReturn(triggerPropagation!))
end
scpiCommand(::typeof(triggerPropagation!), val::Bool) = scpiCommand(triggerPropagation!, val ? "ON" : "OFF")
scpiCommand(::typeof(triggerPropagation!), val::String) = string("RP:TRIGger:PROP ", val)
scpiReturn(::typeof(triggerPropagation!)) = Bool
"""
triggerPropagation(rp::RedPitaya)
Determine whether the trigger propagation is set.
# Example
```julia
julia> triggerPropagation!(rp, true)
julia>triggerPropagation(rp)
true
```
"""
triggerPropagation(rp::RedPitaya) = occursin("ON", query(rp, scpiCommand(triggerPropagation)))
scpiCommand(::typeof(triggerPropagation)) = "RP:TRIGger:PROP?"
scpiReturn(::typeof(triggerPropagation)) = String
parseReturn(::typeof(triggerPropagation), ret) = occursin("ON", ret)


overwritten(rp::RedPitaya) = query(rp, scpiCommand(overwritten), scpiReturn(overwritten))
scpiCommand(::typeof(overwritten)) = "RP:STATus:OVERwritten?"
scpiReturn(::typeof(overwritten)) = Bool
Expand Down
32 changes: 25 additions & 7 deletions src/client/julia/src/Cluster.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export RedPitayaCluster, master, numChan
export RedPitayaCluster, master, numChan, ClusterTriggerSetup

import Base: length, iterate, getindex, firstindex, lastindex

@enum ClusterTriggerSetup ALL_INTERNAL ALL_EXTERNAL MASTER_EXTERNAL
"""
RedPitayaCluster
Expand Down Expand Up @@ -33,14 +34,28 @@ julia> rp == rpc[1]
true
```
"""
function RedPitayaCluster(hosts::Vector{String}, port::Int64=5025, dataPort::Int64=5026; triggerMode_="EXTERNAL")
function RedPitayaCluster(hosts::Vector{String}, port::Int64=5025, dataPort::Int64=5026; triggerMode::ClusterTriggerSetup=ALL_INTERNAL)
# the first RP is the master
rps = RedPitaya[ RedPitaya(host, port, dataPort, i==1) for (i,host) in enumerate(hosts) ]

modes = nothing
if triggerMode == ALL_INTERNAL
modes = fill(INTERNAL, length(rps))
elseif triggerMode == ALL_EXTERNAL
modes = fill(EXTERNAL, length(rps))
elseif triggerMode == MASTER_EXTERNAL
modes = fill(INTERNAL, length(rps))
modes[1] = EXTERNAL
end
@sync for (i, rp) in enumerate(rps)
@async triggerMode!(rp, i == 1 ? INTERNAL : triggerMode_)
@async begin
triggerMode!(rp, modes[i])
triggerPropagation!(rp, true)
end
end

triggerPropagation!(rps[end], false)

return RedPitayaCluster(rps)
end

Expand Down Expand Up @@ -87,9 +102,9 @@ end
for op in [:currentFrame, :currentPeriod, :currentWP, :periodsPerFrame, :samplesPerPeriod, :decimation, :keepAliveReset,
:triggerMode, :samplesPerStep, :serverMode, :masterTrigger,
:counterTrigger_enabled, :counterTrigger_enabled!, :counterTrigger_presamples,
:counterTrigger_presamples!, :counterTrigger_isArmed, :counterTrigger_arm!,
:counterTrigger_reset, :counterTrigger_reset!, :counterTrigger_lastCounter,
:counterTrigger_referenceCounter, :counterTrigger_referenceCounter!]
:counterTrigger_isArmed, :counterTrigger_arm!, :counterTrigger_reset!,
:counterTrigger_reset, :counterTrigger_lastCounter, :counterTrigger_referenceCounter,
:counterTrigger_sourceType, :counterTrigger_sourceChannel]

@eval begin
@doc """
Expand All @@ -103,7 +118,10 @@ for op in [:currentFrame, :currentPeriod, :currentWP, :periodsPerFrame, :samples
end

for op in [:periodsPerFrame!, :samplesPerPeriod!, :decimation!, :triggerMode!, :samplesPerStep!,
:keepAliveReset!, :serverMode!, :stopTransmission]
:keepAliveReset!, :serverMode!, :stopTransmission,
:counterTrigger_enabled!, :counterTrigger_presamples!, :counterTrigger_arm!,
:counterTrigger_reset!, :counterTrigger_referenceCounter!,
:counterTrigger_sourceType!, :counterTrigger_sourceChannel!]
@eval begin
@doc """
$($op)(rpc::RedPitayaCluster, value)
Expand Down
130 changes: 130 additions & 0 deletions src/examples/julia/counterTriggerCluster.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
using RedPitayaDAQServer
using PyPlot
using Statistics
using Base.Threads

# For this example, the ports DIO7_P and DIO2_N have to be connected by a jumper cable.

# Obtain the URL of the RedPitaya
include("config.jl")

# Establish connection to the RedPitaya
rpc = RedPitayaCluster(URLs)

# Set server in CONFIGURATION mode, s.t. we can prepare our signal generation + acquisition
serverMode!(rpc, CONFIGURATION) # or serverMode!(rp, "CONFIGURATION")

counterTrigger_reset!(rpc)
counterTrigger_sourceType!(rpc, COUNTER_TRIGGER_DIO)
counterTrigger_sourceChannel!(rpc, DIO7_P)
DIODirection!(rpc[1], DIO7_P, DIO_IN)
DIODirection!(rpc[1], DIO2_N, DIO_OUT)
counterTrigger_enabled!(rpc, true)

# This simulates a mechanical rotation with a 1 bit encoder which should be synchronized with the data acquisition
function rotationSimulation(timer)
DIO!(rpc[1], DIO2_N, true)
sleep(0.1)
DIO!(rpc[1], DIO2_N, false)
end

timerInterval = 3
t = Timer(rotationSimulation, 0.05, interval=timerInterval)

@info "Determining average rotation time (in clock cycles)"
N = 5
counterValue = zeros(N)
i = 1
savedCounter = 0
outlierFactor = 2
while i <= N
lastCounter = counterTrigger_lastCounter(rpc)

if lastCounter > timerInterval*1e9/8*outlierFactor || lastCounter < timerInterval*1e9/4/outlierFactor
continue
end

if lastCounter != savedCounter
global savedCounter = lastCounter
counterValue[i] = savedCounter
@info savedCounter
global i += 1
end

sleep(0.1)
end

meanCounter = mean(counterValue)
@info "The average rotation time is $(meanCounter*8/1e9) s with a standard deviation of $(std(counterValue)*8/1e6) ms."

counterTrigger_referenceCounter!(rpc, round(Int64, meanCounter))
counterTrigger_presamples!(rpc, 50000000)

dec = 100
modulus = 5000
base_frequency = 125000000
samples_per_period = div(modulus, dec)
periods_per_frame = 2

# ADC Configuration
# These commands are only allowed in CONFIGURATION mode
decimation!(rpc, dec)
samplesPerPeriod!(rpc, samples_per_period)
periodsPerFrame!(rpc, periods_per_frame)
triggerMode!(rpc, INTERNAL) # or triggerMode!(rp, "INTERNAL")

# DAC Configuration
# These commands are allowed during an acquisition
frequencyDAC!(rpc, 1, 1, base_frequency / modulus)
signalTypeDAC!(rpc, 1 , 1, SINE) # or signalTypeDAC!(rp, 1, "SINE")
amplitudeDAC!(rpc, 1, 1, 0.5)
offsetDAC!(rpc, 1, 0)
phaseDAC!(rpc, 1, 1, 0.0)

# Start signal generation + acquisition
# The trigger can only be set in ACQUISITION mode
serverMode!(rpc, ACQUISITION)
masterTrigger!(rpc, true)
counterTrigger_arm!(rpc)

# Transmit the first frame
uFirstPeriod = readFrames(rpc, 0, 1)

sleep(0.1)

# Transmit the current frame
fr = currentFrame(rpc)
# Dimensions of frames are [samples channel, period, frame]
uCurrentPeriod = readFrames(rpc, fr, 1)
sleep(0.2)

uLastPeriod = readFrames(rpc, currentFrame(rpc), 1)

# Stop signal generation + acquisition
masterTrigger!(rpc, false)
serverMode!(rpc, CONFIGURATION)

counterTrigger_enabled!(rpc, false)

close(t)

figure(1)
clf()
chan = 3
# Frame dimensions are [samples, chan, periods, frames]
plot(vec(uFirstPeriod[:,chan,:,:]))
plot(vec(uCurrentPeriod[:,chan,:,:]))
plot(vec(uLastPeriod[:,chan,:,:]))
legend(("first period", "current period", "last period"))
savefig("images/counterTrigger.png")

#==
0: enable
1: trigger_arm
2: trigger_reset
3: trigger (trigger_out)
4: trigger_armed
5: DIO7_P
6: source_select[4]
7: triggerState
==#
5 changes: 3 additions & 2 deletions src/fpga/bd/bd.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -3358,10 +3358,11 @@ proc create_root_design { parentCell } {
connect_bd_net -net proc_sys_reset_write_to_ram_peripheral_aresetn [get_bd_pins proc_sys_reset_write_to_ram/peripheral_aresetn] [get_bd_pins write_to_ram/aresetn]
connect_bd_net -net proc_sys_reset_xadc_peripheral_aresetn [get_bd_pins proc_sys_reset_xadc/peripheral_aresetn] [get_bd_pins xadc_wiz_0/s_axi_aresetn]
connect_bd_net -net reset_manager_0_bram_aresetn [get_bd_pins proc_sys_reset_bram/ext_reset_in] [get_bd_pins reset_manager_0/bram_aresetn]
connect_bd_net -net reset_manager_0_fourier_synth_aresetn [get_bd_pins proc_sys_reset_fourier_synth/ext_reset_in] [get_bd_pins reset_manager_0/fourier_synth_aresetn] [get_bd_pins selectio_wiz_1/data_out_from_device]
connect_bd_net -net reset_manager_0_fourier_synth_aresetn [get_bd_pins proc_sys_reset_fourier_synth/ext_reset_in] [get_bd_pins reset_manager_0/fourier_synth_aresetn]
connect_bd_net -net reset_manager_0_pdm_aresetn [get_bd_pins proc_sys_reset_pdm/ext_reset_in] [get_bd_pins reset_manager_0/pdm_aresetn]
connect_bd_net -net reset_manager_0_ramping_enable [get_bd_pins fourier_synth_standard/enable_ramping] [get_bd_pins reset_manager_0/ramping_enable]
connect_bd_net -net reset_manager_0_reset_sts [get_bd_pins reset_manager_0/reset_sts] [get_bd_pins system/reset_sts] [get_bd_pins xlslice_triggerState/Din]
connect_bd_net -net reset_manager_0_sata_out [get_bd_pins reset_manager_0/sata_out] [get_bd_pins selectio_wiz_1/data_out_from_device]
connect_bd_net -net reset_manager_0_start_ramp_down [get_bd_pins fourier_synth_standard/start_ramp_down] [get_bd_pins reset_manager_0/start_ramp_down]
connect_bd_net -net reset_manager_0_write_to_ram_aresetn [get_bd_pins proc_sys_reset_write_to_ram/ext_reset_in] [get_bd_pins reset_manager_0/write_to_ram_aresetn]
connect_bd_net -net reset_manager_0_xadc_aresetn [get_bd_pins proc_sys_reset_xadc/ext_reset_in] [get_bd_pins reset_manager_0/xadc_aresetn]
Expand All @@ -3378,7 +3379,7 @@ proc create_root_design { parentCell } {
connect_bd_net -net system_peripheral_aresetn [get_bd_pins reset_manager_0/peripheral_aresetn] [get_bd_pins system/peripheral_aresetn]
connect_bd_net -net util_ds_buf_0_OBUF_DS_N [get_bd_ports adc_enc_n_o] [get_bd_pins util_ds_buf_0/OBUF_DS_N]
connect_bd_net -net util_ds_buf_0_OBUF_DS_P [get_bd_ports adc_enc_p_o] [get_bd_pins util_ds_buf_0/OBUF_DS_P]
connect_bd_net -net util_vector_logic_0_Res [get_bd_pins clk_wiz_0/clk_in_sel] [get_bd_pins util_vector_logic_0/Res]
connect_bd_net -net util_vector_logic_0_Res [get_bd_pins clk_wiz_0/clk_in_sel] [get_bd_pins reset_manager_0/isMaster] [get_bd_pins util_vector_logic_0/Res]
connect_bd_net -net write_to_ram_adc_out_A [get_bd_pins counter_trigger/adc0] [get_bd_pins write_to_ram/adc_out_A]
connect_bd_net -net write_to_ram_adc_out_B [get_bd_pins counter_trigger/adc1] [get_bd_pins write_to_ram/adc_out_B]
connect_bd_net -net xlconcat_0_dout [get_bd_pins sequencer/adc_sts] [get_bd_pins system/adc_sts] [get_bd_pins write_to_ram/sts_data]
Expand Down
7 changes: 5 additions & 2 deletions src/fpga/hdl/reset_manager.v
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ module reset_manager #
)
(
input clk,
input isMaster,
input peripheral_aresetn,
input [7:0] reset_cfg,
input sata_trigger,
output sata_out,
inout trigger,
inout watchdog,
inout instant_reset,
Expand Down Expand Up @@ -39,7 +41,7 @@ module reset_manager #
reset_cfg:
Bit 0 => 0: continuous mode; 1: trigger mode
Bit 1 => 0: no watchdog; 1: watchdog mode
Bit 2 => unused
Bit 2 => Sata Trigger Propagation
Bit 3 => instant reset mode: 0: disabled; 1: enabled
Bit 4 => 0: internal trigger 1: external trigger
Bit 5 => internal trigger enable/disable, output over DIO5_P
Expand Down Expand Up @@ -207,7 +209,7 @@ always @(posedge clk)
begin
if (reset_cfg[4] == 0) // internal trigger mode
begin
triggerState <= reset_cfg[5] & counter_trigger; // counter_trigger must always be high if not enabled
triggerState <= (reset_cfg[5] & counter_trigger) || (!isMaster & sata_trigger_int); // counter_trigger must always be high if not enabled
end
else
begin
Expand Down Expand Up @@ -291,6 +293,7 @@ assign reset_ack_out = watchdog_in; // Acknowledge received watchdog signal

assign alive_signal_out = alive_signal_int;
assign master_trigger_out = masterTriggerState;
assign sata_out = triggerState & reset_cfg[2];

assign ramping_enable[0] = ramping_cfg[0];
assign ramping_enable[1] = ramping_cfg[1];
Expand Down
24 changes: 24 additions & 0 deletions src/lib/rp-daq-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,30 @@ int setTriggerMode(int mode) {
return 0;
}

int getTriggerPropagation() {
int value = (((int)(*((uint8_t *)(cfg + 1))) & 0x04) >> 2);

if(value == 0) {
return OFF;
} else if(value == 1) {
return ON;
}

return -1;
}

int setTriggerPropagation(int mode) {
if(mode == OFF) {
*((uint8_t *)(cfg + 1)) &= ~4;
} else if(mode == ON) {
*((uint8_t *)(cfg + 1)) |= 4;
} else {
return -1;
}

return 0;
}

int getMasterTrigger() {
int value;

Expand Down
2 changes: 2 additions & 0 deletions src/lib/rp-daq-lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ extern int setDIO(const char*, int);
extern int getDIO(const char*);
extern int setTriggerMode(int);
extern int getTriggerMode();
extern int setTriggerPropagation(int);
extern int getTriggerPropagation();
extern int getWatchdogMode();
extern int setWatchdogMode(int);
extern int getRAMWriterMode();
Expand Down
10 changes: 5 additions & 5 deletions src/server/daq_server_scpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,6 @@ int main(int argc, char** argv) {

logger_flush();

if(!initialized) {
init();
initialized = true;
}

int rc;
int listenfd;

Expand Down Expand Up @@ -293,6 +288,11 @@ int main(int argc, char** argv) {
joinControlThread();
}

if(!initialized) {
init();
initialized = true;
}

newdatasocklen = sizeof(newdatasockaddr);
newdatasockfd = accept(datasockfd, (struct sockaddr *) &newdatasockaddr, &newdatasocklen);

Expand Down
Loading

0 comments on commit 712c003

Please sign in to comment.