Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resync Phase Offset and Frequency #90

Merged
merged 20 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/client/julia/Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "RedPitayaDAQServer"
uuid = "c544963a-496b-56d4-a5fe-f99a3f174c8f"
authors = ["Tobias Knopp <[email protected]>"]
version = "0.8.1"
version = "0.9.0"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
4 changes: 4 additions & 0 deletions src/client/julia/src/ADC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ julia> decimation(rp)
```
"""
function decimation!(rp::RedPitaya, dec)
if dec < 8 || dec > 8192 || mod(dec, 2) != 0
error("Decimation must be an even value between 8 and 8192. Supplied value is $dec.")
end

rp.decimation = Int64(dec)
return query(rp, scpiCommand(decimation!, rp.decimation), scpiReturn(decimation!))
end
Expand Down
16 changes: 12 additions & 4 deletions src/client/julia/src/Acquisition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function readSamplesHeartbeat(rpu::Union{RedPitaya,RedPitayaCluster, RedPitayaCl
# Current WP query as a heartbeat to avoid timeouts with "distant" wpStarts
timeDifference = time() - heartBeatStartTime
if timeDifference / (heartbeatTimeout*1000.0) >= timeOutCounter
@warn "Still waiting for write pointer (currently it is $(currentWP(rpu)). Are you sure there is no error and this loop is running infinitely?"
@warn "Still waiting for write pointer (currently it is $(currentWP(rpu))). Are you sure there is no error and this loop is running infinitely?"
timeOutCounter += 1
end
end
Expand All @@ -53,6 +53,11 @@ function correctFilterDelay(wpStart::Int64, dec::Int64)
return correctedWp
end

# See https://support.xilinx.com/s/question/0D52E00006hpfy6SAA/cic-filter-gain?language=en_US
gain_cic(rp::RedPitaya) = gain_cic(round(Int, rp.decimation / 2), 1, 6) # M and N are fixed due to the FPGA image settings
gain_cic(rpc::RedPitayaCluster) = gain_cic(round(Int, master(rpc).decimation / 2), 1, 6) # M and N are fixed due to the FPGA image settings
gain_cic(rpcv::RedPitayaClusterView) = gain_cic(rpcv.rpc)
gain_cic(R::Int64, M::Int64, N::Int64) = ((R * M)^N) / 2^(ceil(N * log2(R * M)))

"""
readSamples(rpu::Union{RedPitaya,RedPitayaCluster, RedPitayaClusterView}, wpStart::Int64, numOfRequestedSamples::Int64; chunkSize::Int64 = 25000, rpInfo=nothing)
Expand Down Expand Up @@ -220,8 +225,9 @@ function convertSamplesToFrames(rpu::Union{RedPitaya, RedPitayaCluster, RedPitay
frames = convertSamplesToFrames(samples, numChan, numSampPerPeriod, numPeriods, numFrames, numBlockAverages, numPeriodsPerPatch)
calibs = [x.calib for x in rpu]
calib = hcat(calibs...)
gainCorr_ = 1 / gain_cic(rpu)
for d = 1:size(frames, 2)
frames[:, d, :, :] .*= calib[1, d]
frames[:, d, :, :] .*= calib[1, d] * gainCorr_
frames[:, d, :, :] .+= calib[2, d]
end
return frames
Expand Down Expand Up @@ -255,8 +261,9 @@ function convertSamplesToFrames!(rpu::Union{RedPitaya, RedPitayaCluster, RedPita
convertSamplesToFrames!(samples, frames, numChan, numSampPerPeriod, numPeriods, numFrames, numTrueSampPerPeriod, numBlockAverages, numPeriodsPerPatch)
calibs = [x.calib for x in rpu]
calib = hcat(calibs...)
gainCorr_ = 1 / gain_cic(rpu)
for d = 1:size(frames, 2)
frames[:, d, :, :] .*= calib[1, d]
frames[:, d, :, :] .*= calib[1, d] * gainCorr_
frames[:, d, :, :] .+= calib[2, d]
end
end
Expand Down Expand Up @@ -331,8 +338,9 @@ function convertSamplesToPeriods!(rpu::Union{RedPitaya, RedPitayaCluster, RedPit
convertSamplesToPeriods!(samples, periods, numChan, numSampPerPeriod, numPeriods, numBlockAverages)
calibs = [x.calib for x in rpu]
calib = hcat(calibs...)
gainCorr_ = 1 / gain_cic(rpu)
for d = 1:size(periods, 2)
periods[:, d, :] .*= calib[1, d]
periods[:, d, :] .*= calib[1, d] * gainCorr_
periods[:, d, :] .+= calib[2, d]
end
return periods
Expand Down
7 changes: 4 additions & 3 deletions src/client/julia/src/Cluster.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,16 @@ function RedPitayaCluster(hosts::Vector{String}, port::Int64=5025, dataPort::Int
modes = fill(INTERNAL, length(rps))
modes[1] = EXTERNAL
end
@sync for (i, rp) in enumerate(rps)
@async begin

@sync for (i, rp) ∈ enumerate(rps)
@async begin
triggerMode!(rp, modes[i])
triggerPropagation!(rp, true)
end
end

triggerPropagation!(rps[end], false)

return RedPitayaCluster(rps)
end

Expand Down
64 changes: 47 additions & 17 deletions src/client/julia/src/Sequence.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ Struct representing a sequence in which the server directly takes the values fro
"""
struct SimpleSequence <: AbstractSequence
lut::SequenceLUT
enable::Union{Array{Bool}, Nothing}
enable::Union{Matrix{Bool}, Nothing}
resync::Union{Matrix{Bool}, Nothing}
"""
SimpleSequence(lut, repetitions, enable=nothing)

Expand All @@ -114,17 +115,18 @@ struct SimpleSequence <: AbstractSequence
- `repetitions::Int32`: the number of times the sequence should be repeated
- `emable::Union{Array{Bool}, Nothing}`: matrix containing enable flags
"""
function SimpleSequence(lut::Array{Float32}, repetitions::Integer, enable::Union{Array{Bool}, Nothing}=nothing)
function SimpleSequence(lut::Matrix{Float32}, repetitions::Integer, enable::Union{Matrix{Bool}, Nothing}=nothing, resync::Union{Matrix{Bool}, Nothing} = nothing)
if !isnothing(enable) && size(lut) != size(enable)
throw(DimensionMismatch("Size of enable LUT does not match size of value LUT"))
end
return new(SequenceLUT(lut, repetitions), enable)
return new(SequenceLUT(lut, repetitions), enable, resync)
end
end
SimpleSequence(lut::Array{T}, repetitions::Integer, enable::Union{Array{Bool}, Nothing}=nothing) where T <: Real = SimpleSequence(map(Float32, lut), repetitions, enable)
SimpleSequence(lut::Vector{T}, repetitions::Integer, enable::Union{Array{Bool}, Nothing}=nothing) where T <: Real = SimpleSequence(reshape(lut, 1, :), repetitions, enable)
SimpleSequence(lut::Array{T}, repetitions::Integer, args...) where T <: Real = SimpleSequence(map(Float32, lut), repetitions, args...)
SimpleSequence(lut::Vector{T}, repetitions::Integer, args...) where T <: Real = SimpleSequence(reshape(lut, 1, :), repetitions, args...)

enableLUT(seq::SimpleSequence) = seq.enable
resyncLUT(seq::SimpleSequence) = seq.resync
valueLUT(seq::SimpleSequence) = seq.lut
rampUpLUT(seq::SimpleSequence) = nothing
rampDownLUT(seq::SimpleSequence) = nothing
Expand All @@ -134,17 +136,19 @@ abstract type RampingSequence <: AbstractSequence end
struct SimpleRampingSequence <: AbstractSequence
lut::SequenceLUT
enable::Union{Array{Bool}, Nothing}
resync::Union{Array{Bool}, Nothing}
rampUp::SequenceLUT
rampDown::SequenceLUT
function SimpleRampingSequencee(lut::SequenceLUT, up::SequenceLUT, down::SequenceLUT, enable::Union{Array{Bool}, Nothing}=nothing)
function SimpleRampingSequencee(lut::SequenceLUT, up::SequenceLUT, down::SequenceLUT, enable::Union{Array{Bool}, Nothing}=nothing, resync::Union{Array{Bool}, Nothing}=nothing)
if !isnothing(enable) && size(values(lut)) != size(enable)
throw(DimensionMismatch("Size of enable LUT does not match size of value LUT"))
end
return new(SequenceLUT(lut, repetitions), enable, up, down)
return new(SequenceLUT(lut, repetitions), enable, resync, up, down)
end
end

enableLUT(seq::SimpleRampingSequence) = seq.enable
resyncLUT(seq::SimpleRampingSequence) = seq.resync
valueLUT(seq::SimpleRampingSequence) = seq.lut
rampUpLUT(seq::SimpleRampingSequence) = nothing
rampDownLUT(seq::SimpleRampingSequence) = nothing
Expand All @@ -158,6 +162,7 @@ end
struct HoldBorderRampingSequence <: RampingSequence
lut::SequenceLUT
enable::Union{Array{Bool}, Nothing}
resync::Union{Array{Bool}, Nothing}
rampUp::SequenceLUT
rampDown::SequenceLUT

Expand All @@ -170,13 +175,13 @@ struct HoldBorderRampingSequence <: RampingSequence
- `lut`,`repetitions`,`enable` are used the same as for a `SimpleSequence`
- `rampingSteps` is the number of steps the first and last value of the given sequence are repeated before the sequence is started
"""
function HoldBorderRampingSequence(lut::Array{Float32}, repetitions::Integer, rampingSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing)
function HoldBorderRampingSequence(lut::Array{Float32}, repetitions::Integer, rampingSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing, resync::Union{Array{Bool}, Nothing}=nothing)
if !isnothing(enable) && size(lut) != size(enable)
throw(DimensionMismatch("Size of enable LUT does not match size of value LUT"))
end
up = SequenceLUT(lut[:, 1], rampingSteps)
down = SequenceLUT(lut[:, end], rampingSteps)
return new(SequenceLUT(lut, repetitions), enable, up, down)
return new(SequenceLUT(lut, repetitions), enable, resync, up, down)
end
end

Expand All @@ -190,38 +195,42 @@ function HoldBorderRampingSequence(rp::RedPitaya, lut, repetitions, enable=nothi
end

enableLUT(seq::HoldBorderRampingSequence) = seq.enable
resyncLUT(seq::HoldBorderRampingSequence) = seq.resync
valueLUT(seq::HoldBorderRampingSequence) = seq.lut
rampUpLUT(seq::HoldBorderRampingSequence) = seq.rampUp
rampDownLUT(seq::HoldBorderRampingSequence) = seq.rampDown

struct ConstantRampingSequence <: RampingSequence
lut::SequenceLUT
enable::Union{Array{Bool}, Nothing}
resync::Union{Array{Bool}, Nothing}
ramping::SequenceLUT

function ConstantRampingSequence(lut::Array{Float32}, repetitions::Integer, rampingValue::Float32, rampingSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing)
function ConstantRampingSequence(lut::Array{Float32}, repetitions::Integer, rampingValue::Float32, rampingSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing, resync::Union{Array{Bool}, Nothing}=nothing)
if !isnothing(enable) && size(lut) != size(enable)
throw(DimensionMismatch("Size of enable LUT does not match size of value LUT"))
end
rampingLut = SequenceLUT([rampingValue for i = 1:size(lut, 1)], rampingSteps)
return new(SequenceLUT(lut, repetitions), enable, rampingLut)
return new(SequenceLUT(lut, repetitions), enable, resync, rampingLut)
end
end
ConstantRampingSequence(lut::Array{T}, repetitions::Integer, rampingValue::Real, rampingSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing) where T <: Real = ConstantRampingSequence(map(Float32, lut), repetitions, Float32(rampingValue), rampingSteps, enable)
ConstantRampingSequence(lut::Vector{Float32}, repetitions::Integer, rampingValue::Float32, rampingSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing) = ConstantRampingSequence(reshape(lut, 1, :), repetitions, rampingValue, rampingSteps, enable)
ConstantRampingSequence(lut::Vector{T}, repetitions::Integer, rampingValue::Real, rampingSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing) where T <: Real = ConstantRampingSequence(reshape(lut, 1, :), repetitions, rampingValue, rampingSteps, enable)

enableLUT(seq::ConstantRampingSequence) = seq.enable
resyncLUT(seq::ConstantRampingSequence) = seq.resync
valueLUT(seq::ConstantRampingSequence) = seq.lut
rampUpLUT(seq::ConstantRampingSequence) = seq.ramping
rampDownLUT(seq::ConstantRampingSequence) = seq.ramping

struct StartUpSequence <: RampingSequence
lut::SequenceLUT
enable::Union{Array{Bool}, Nothing}
resync::Union{Array{Bool}, Nothing}
rampUp::SequenceLUT
rampDown::SequenceLUT
function StartUpSequence(lut::Array{Float32}, repetitions::Integer, rampingSteps::Integer, startUpSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing)
function StartUpSequence(lut::Array{Float32}, repetitions::Integer, rampingSteps::Integer, startUpSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing, resync::Union{Array{Bool}, Nothing}=nothing)
if !isnothing(enable) && size(lut) != size(enable)
throw(DimensionMismatch("Size of enable LUT does not match size of value LUT"))
end
Expand All @@ -239,14 +248,15 @@ struct StartUpSequence <: RampingSequence
end
up = SequenceLUT(upLut, 1)
down = SequenceLUT(lut[:, end], rampingSteps)
return new(SequenceLUT(lut, repetitions), enable, up, down)
return new(SequenceLUT(lut, repetitions), enable, resync, up, down)
end
end
StartUpSequence(lut::Array{T}, repetitions::Integer, rampingSteps::Integer, startUpSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing) where T <: Real = StartUpSequence(map(Float32, lut), repetitions, rampingSteps, startUpSteps, enable)
#StartUpSequence(lut::Vector{Float32}, repetitions::Integer, rampingSteps::Integer, startUpSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing) = StartUpSequence(reshape(lut, 1, :), repetitions, rampingSteps, startUpSteps, enable)
StartUpSequence(lut::Vector{T}, repetitions::Integer, rampingSteps::Integer, startUpSteps::Integer, enable::Union{Array{Bool}, Nothing}=nothing) where T <: Real = StartUpSequence(reshape(lut, 1, :), repetitions, rampingSteps, startUpSteps, enable)

enableLUT(seq::StartUpSequence) = seq.enable
resyncLUT(seq::StartUpSequence) = seq.resync
valueLUT(seq::StartUpSequence) = seq.lut
rampUpLUT(seq::StartUpSequence) = seq.rampUp
rampDownLUT(seq::StartUpSequence) = seq.rampDown
Expand All @@ -269,10 +279,11 @@ Transmit the client-side representation `seq` to the server and append it to the
"""
function sequence!(rp::RedPitaya, seq::AbstractSequence)
result = true
result &= valueLUT!(rp, valueLUT(seq))
result &= enableLUT!(rp, enableLUT(seq))
result &= rampUpLUT!(rp, rampUpLUT(seq))
result &= rampDownLUT!(rp, rampDownLUT(seq))
result &= valueLUT!(rp, seq)
result &= enableLUT!(rp, seq)
result &= resyncLUT!(rp, seq)
result &= rampUpLUT!(rp, seq)
result &= rampDownLUT!(rp, seq)
result &= setSequence!(rp)
return result
end
Expand All @@ -283,11 +294,13 @@ function transmitLUT!(rp::RedPitaya, lut::Array{Float32}, cmd::String, repetitio
return parse(Bool, receive(rp))
end

valueLUT!(rp::RedPitaya, lut::AbstractSequence) = valueLUT!(rp, valueLUT(lut))
function valueLUT!(rp::RedPitaya, lut::SequenceLUT)
lutFloat32 = map(Float32, values(lut))
return transmitLUT!(rp, lutFloat32, "RP:DAC:SEQ:LUT", repetitions(lut))
end

rampUpLUT!(rp::RedPitaya, lut::AbstractSequence) = rampUpLUT!(rp, rampUpLUT(lut))
function rampUpLUT!(rp::RedPitaya, lut::SequenceLUT)
lutFloat32 = map(Float32, values(lut))
return transmitLUT!(rp, lutFloat32, "RP:DAC:SEQ:LUT:UP", repetitions(lut))
Expand All @@ -298,6 +311,7 @@ function rampUpLUT!(rp::RedPitaya, lut::Nothing)
return true
end

rampDownLUT!(rp::RedPitaya, lut::AbstractSequence) = rampDownLUT!(rp, rampDownLUT(lut))
function rampDownLUT!(rp::RedPitaya, lut::SequenceLUT)
lutFloat32 = map(Float32, values(lut))
return transmitLUT!(rp, lutFloat32, "RP:DAC:SEQ:LUT:DOWN", repetitions(lut))
Expand All @@ -308,6 +322,7 @@ function rampDownLUT!(rp::RedPitaya, lut::Nothing)
return true
end

enableLUT!(rp::RedPitaya, lut::AbstractSequence) = enableLUT!(rp, enableLUT(lut))
function enableLUT!(rp::RedPitaya, lut::Array)
lutBool = map(Bool, lut)
send(rp, string("RP:DAC:SEQ:LUT:ENaBle"))
Expand All @@ -322,6 +337,21 @@ function enableLUT!(rp::RedPitaya, lut::Nothing)
return true
end

resyncLUT!(rp::RedPitaya, lut::AbstractSequence) = resyncLUT!(rp, resyncLUT(lut))
function resyncLUT!(rp::RedPitaya, lut::Array)
lutBool = map(Bool, lut)
send(rp, string("RP:DAC:SEQ:LUT:ReSYNC"))
@debug "Writing resync DAC LUT"
write(rp.dataSocket, lutBool)
reply = receive(rp)
return parse(Bool, reply)
end

function resyncLUT!(rp::RedPitaya, lut::Nothing)
# NOP
return true
end

function seqTiming(seq::AbstractSequence)
up = 0
if !isnothing(rampUpLUT(seq))
Expand Down
60 changes: 60 additions & 0 deletions src/examples/julia/sequenceIssue.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using RedPitayaDAQServer
using CairoMakie

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

rp = RedPitaya(URLs[1])
serverMode!(rp, CONFIGURATION)


dec = 128
base_frequency = 125000000

samples_per_step = 40 #30*16
steps_per_frame = 4
numSamples = steps_per_frame * samples_per_step

decimation!(rp, dec)
samplesPerPeriod!(rp, 1)
periodsPerFrame!(rp, numSamples)
samplesPerStep!(rp, samples_per_step)
triggerMode!(rp, INTERNAL)


amplitudeDAC!(rp, 1, 1, 0.0)
amplitudeDAC!(rp, 2, 1, 0.0 )

clearSequence!(rp)

# Climbing offset for first channel, fixed offset for second channel
seqChan!(rp, 6)
lutB = collect(ones(steps_per_frame))
lutB[1:2:end] .= 0.0
lut = collect(cat(-lutB,-lutB*0.3, 0*lutB,0*lutB,0*lutB,0*lutB,dims=2)')
#lut = collect(cat(-lutB,dims=2)')#,lutB,lutB,lutB,lutB,dims=2)')

lutEnableDACA = ones(Bool, steps_per_frame)

#enableLUT = collect( cat(lutEnableDACA,lutEnableDACA,lutEnableDACA,lutEnableDACA,lutEnableDACA,lutEnableDACA,dims=2)' )
enableLUT = collect( cat(lutEnableDACA,lutEnableDACA,lutEnableDACA,lutEnableDACA,lutEnableDACA,lutEnableDACA,dims=2)' )
#enableLUT = collect( cat(lutEnableDACA,dims=2)') #,lutEnableDACA,lutEnableDACA,lutEnableDACA,lutEnableDACA,dims=2)' )

seq = SimpleSequence(lut, 300, enableLUT)
sequence!(rp, seq)

serverMode!(rp, ACQUISITION)
masterTrigger!(rp, true)

uCurrentPeriod = readFrames(rp, 1, 3)

masterTrigger!(rp, false)
serverMode!(rp, CONFIGURATION)

plot = lines(vec(uCurrentPeriod[:,1,:,1]), label = "Rx1")
lines!(plot.axis, vec(uCurrentPeriod[:,2,:,1]), label = "Rx2")
lines!(plot.axis, vec(uCurrentPeriod[:,1,:,2]), label = "Rx1_2")
lines!(plot.axis, vec(uCurrentPeriod[:,2,:,2]), label = "Rx2_2")
axislegend(plot.axis)
save(joinpath(@__DIR__(), "images", "sequenceIssue.png"), plot)
plot
Loading