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

Saturate fast DAC Signals with calibrated upper and lower limits #72

Merged
merged 8 commits into from
Dec 1, 2023
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
56 changes: 55 additions & 1 deletion src/client/julia/src/EEPROM.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export calibDACOffset, calibDACOffset!, calibADCScale, calibADCScale!, calibADCOffset, calibADCOffset!, updateCalib!, calibDACScale!, calibDACScale, calibFlags
export calibDACOffset, calibDACOffset!, calibADCScale, calibADCScale!, calibADCOffset, calibADCOffset!, updateCalib!, calibDACScale!, calibDACScale, calibFlags, calibDACLowerLimit, calibDACLowerLimit!, calibDACUpperLimit, calibDACUpperLimit!, calibDACLimit!

"""
calibDACOffset!(rp::RedPitaya, channel::Integer, val)
Expand Down Expand Up @@ -43,6 +43,60 @@ calibDACScale(rp::RedPitaya, channel::Integer) = query(rp, scpiCommand(calibDACS
scpiCommand(::typeof(calibDACScale), channel::Integer) = string("RP:CALib:DAC:CH", Int(channel) - 1, ":SCA?")
scpiReturn(::typeof(calibDACScale)) = Float64

"""
calibDACLowerLimit!(rp::RedPitaya, channel::Integer)

Store calibration DAC lower limit `val` for given channel into the RedPitayas EEPROM.
This value is used by the server to limit the output voltage.
"""
function calibDACLowerLimit!(rp::RedPitaya, channel::Integer, val)
return query(rp, scpiCommand(calibDACLowerLimit!, channel, val), scpiReturn(calibDACLowerLimit!))
end
scpiCommand(::typeof(calibDACLowerLimit!), channel::Integer, val) = string("RP:CALib:DAC:CH", Int(channel) - 1, ":LIM:LOW $(Float32(val))")
scpiReturn(::typeof(calibDACLowerLimit!)) = Bool
"""
calibDACLowerLimit(rp::RedPitaya, channel::Integer)

Retrieve the calibration DAC lower limit for given channel from the RedPitayas EEPROM.
"""
calibDACLowerLimit(rp::RedPitaya, channel::Integer) = query(rp, scpiCommand(calibDACLowerLimit, channel), scpiReturn(calibDACLowerLimit))
scpiCommand(::typeof(calibDACLowerLimit), channel::Integer) = string("RP:CALib:DAC:CH", Int(channel) - 1, ":LIM:LOW?")
scpiReturn(::typeof(calibDACLowerLimit)) = Float64

"""
calibDACUpperLimit!(rp::RedPitaya, channel::Integer)

Store calibration DAC upper limit `val` for given channel into the RedPitayas EEPROM.
This value is used by the server to limit the output voltage.
"""
function calibDACUpperLimit!(rp::RedPitaya, channel::Integer, val)
return query(rp, scpiCommand(calibDACUpperLimit!, channel, val), scpiReturn(calibDACUpperLimit!))
end
scpiCommand(::typeof(calibDACUpperLimit!), channel::Integer, val) = string("RP:CALib:DAC:CH", Int(channel) - 1, ":LIM:UP $(Float32(val))")
scpiReturn(::typeof(calibDACUpperLimit!)) = Bool
"""
calibDACUpperLimit(rp::RedPitaya, channel::Integer)

Retrieve the calibration DAC upper limit for given channel from the RedPitayas EEPROM.
"""
calibDACUpperLimit(rp::RedPitaya, channel::Integer) = query(rp, scpiCommand(calibDACUpperLimit, channel), scpiReturn(calibDACUpperLimit))
scpiCommand(::typeof(calibDACUpperLimit), channel::Integer) = string("RP:CALib:DAC:CH", Int(channel) - 1, ":LIM:UP?")
scpiReturn(::typeof(calibDACUpperLimit)) = Float64

"""
calibDACLimit!(rp::RedPitaya, channel, val)

Applies `val` with a positive sign as the upper and with a negative sign as the lower calibration DAC limit.

See also [calibDACUpperLimit!](@ref), [calibDACLowerLimit!](@ref)
"""
function calibDACLimit!(rp::RedPitaya, channel::Integer, val)
val = abs(val)
result = calibDACLowerLimit!(rp, channel, -val)
result &= calibDACUpperLimit!(rp, channel, val)
return result
end

"""
calibADCOffset!(rp::RedPitaya, channel::Integer, val)

Expand Down
7 changes: 5 additions & 2 deletions src/fpga/bd/bd.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,8 @@ proc create_hier_cell_signal_compose1 { parentCell nameHier } {
connect_bd_net -net offset_1 [get_bd_pins offset] [get_bd_pins signal_composer_0/seq]
connect_bd_net -net rst_ps7_0_125M_peripheral_aresetn [get_bd_pins aresetn] [get_bd_pins signal_ramp_0/aresetn] [get_bd_pins waveform_awg1/aresetn] [get_bd_pins waveform_gen_0/aresetn] [get_bd_pins waveform_gen_1/aresetn] [get_bd_pins waveform_gen_2/aresetn] [get_bd_pins waveform_gen_3/aresetn]
connect_bd_net -net signal_calib_0_signal_out [get_bd_pins S] [get_bd_pins signal_calib_0/signal_out]
connect_bd_net -net signal_cfg_slice_0_calib_limit_lower [get_bd_pins signal_calib_0/calib_limit_lower] [get_bd_pins signal_cfg_slice_0/calib_limit_lower]
connect_bd_net -net signal_cfg_slice_0_calib_limit_upper [get_bd_pins signal_calib_0/calib_limit_upper] [get_bd_pins signal_cfg_slice_0/calib_limit_upper]
connect_bd_net -net signal_cfg_slice_0_calib_offset [get_bd_pins signal_calib_0/calib_offset] [get_bd_pins signal_cfg_slice_0/calib_offset]
connect_bd_net -net signal_cfg_slice_0_calib_scale [get_bd_pins signal_calib_0/calib_scale] [get_bd_pins signal_cfg_slice_0/calib_scale]
connect_bd_net -net signal_cfg_slice_0_comp_0_amp [get_bd_pins signal_cfg_slice_0/comp_0_amp] [get_bd_pins waveform_gen_0/amplitude]
Expand Down Expand Up @@ -1093,6 +1095,8 @@ proc create_hier_cell_signal_compose { parentCell nameHier } {
connect_bd_net -net offset_1 [get_bd_pins offset] [get_bd_pins signal_composer_0/seq]
connect_bd_net -net ramping_enable_1 [get_bd_pins enable_ramping] [get_bd_pins signal_ramp/enableRamping]
connect_bd_net -net signal_calib_0_signal_out [get_bd_pins S] [get_bd_pins signal_calib_0/signal_out]
connect_bd_net -net signal_cfg_slice_0_calib_limit_lower [get_bd_pins signal_calib_0/calib_limit_lower] [get_bd_pins signal_cfg_slice_0/calib_limit_lower]
connect_bd_net -net signal_cfg_slice_0_calib_limit_upper [get_bd_pins signal_calib_0/calib_limit_upper] [get_bd_pins signal_cfg_slice_0/calib_limit_upper]
connect_bd_net -net signal_cfg_slice_0_calib_offset [get_bd_pins signal_calib_0/calib_offset] [get_bd_pins signal_cfg_slice_0/calib_offset]
connect_bd_net -net signal_cfg_slice_0_calib_scale [get_bd_pins signal_calib_0/calib_scale] [get_bd_pins signal_cfg_slice_0/calib_scale]
connect_bd_net -net signal_cfg_slice_0_comp_0_amp [get_bd_pins signal_cfg_slice_0/comp_0_amp] [get_bd_pins waveform_gen_0/amplitude]
Expand Down Expand Up @@ -3413,6 +3417,7 @@ proc create_root_design { parentCell } {
# Restore current instance
current_bd_instance $oldCurInst

validate_bd_design
save_bd_design
}
# End of create_root_design()
Expand All @@ -3425,5 +3430,3 @@ proc create_root_design { parentCell } {
create_root_design ""


common::send_gid_msg -ssname BD::TCL -id 2053 -severity "WARNING" "This Tcl script was generated from a block design that has not been validated. It is possible that design <$design_name> may result in errors during validation."

2 changes: 1 addition & 1 deletion src/fpga/hdl/reset_manager.v
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ begin
end
else
begin
triggerState <= trigger_in_int || sata_trigger_int;
triggerState <= trigger_in_int;
end

masterTriggerState_pre <= reset_cfg[5] & counter_trigger; // counter_trigger must always be high if not enabled
Expand Down
8 changes: 6 additions & 2 deletions src/fpga/hdl/signal_cfg_slice.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ module signal_cfg_slice(
output [15:0] offset,
output [15:0] calib_scale,
output [15:0] calib_offset,
output [15:0] calib_limit_lower,
output [15:0] calib_limit_upper,
output [47:0] comp_0_cfg,
output [15:0] comp_0_amp,
output [47:0] comp_0_freq,
Expand Down Expand Up @@ -35,13 +37,15 @@ assign calib_scale[15:0] = cfg_data[191:176];
assign comp_0_phase[47:0] = cfg_data[239:192];
assign calib_offset[15:0] = cfg_data[255:240];

// 0 bit gap
assign comp_1_cfg[47:0] = cfg_data[303:256];
assign comp_1_amp[15:0] = cfg_data[319:304];
assign comp_1_freq[47:0] = cfg_data[367:320];
// 15 bit gap
assign calib_limit_lower[15:0] = cfg_data[383:368];
assign comp_1_phase[47:0] = cfg_data[431:384];
assign calib_limit_upper[15:0] = cfg_data[447:432];

// 15 bit gap
// 0 bit gap
assign comp_2_cfg[47:0] = cfg_data[495:448];
assign comp_2_amp[15:0] = cfg_data[511:496];
assign comp_2_freq[47:0] = cfg_data[559:512];
Expand Down
26 changes: 26 additions & 0 deletions src/fpga/hdl/signal_limit.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
`timescale 1ns / 1ps


module signal_limit(
input clk,
input signed [15:0] signal_in,
input signed [15:0] limit_upper,
input signed[15:0] limit_lower,
output [15:0] limited_signal
);

reg signed [15:0] signal_result;

always @(posedge clk)
begin
if (signal_in > limit_upper) begin
signal_result <= limit_upper;
end else if (signal_in < limit_lower) begin
signal_result <= limit_lower;
end else begin
signal_result <= signal_in;
end
end

assign limited_signal = signal_result;
endmodule
90 changes: 90 additions & 0 deletions src/lib/rp-daq-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,39 @@ int setCalibDACOffset(float value, int channel) {
return 0;
}

int setCalibDACLowerLimit(float value, int channel) {
if (channel < 0 || channel > 1) {
return -3;
}

int16_t limit = (int16_t)(value*8191.0);
if (limit < -8191 || limit >= 8192) {
return -2;
}
// Config lower limit is stored in second component freq
uint64_t register_value = *(dac_cfg + COMPONENT_START_OFFSET + FREQ_OFFSET + COMPONENT_OFFSET*1 + CHANNEL_OFFSET*channel);
register_value = (register_value & MASK_LOWER_48) | ((((int64_t) limit) << 48) & ~MASK_LOWER_48);
*(dac_cfg + COMPONENT_START_OFFSET + FREQ_OFFSET + COMPONENT_OFFSET*1 + CHANNEL_OFFSET*channel) = register_value;
return 0;
}


int setCalibDACUpperLimit(float value, int channel) {
if (channel < 0 || channel > 1) {
return -3;
}

int16_t limit = (int16_t)(value*8191.0);
if (limit < -8191 || limit >= 8192) {
return -2;
}
// Config upper limit is stored in second component phase
uint64_t register_value = *(dac_cfg + COMPONENT_START_OFFSET + PHASE_OFFSET + COMPONENT_OFFSET*1 + CHANNEL_OFFSET*channel);
register_value = (register_value & MASK_LOWER_48) | ((((int64_t) limit) << 48) & ~MASK_LOWER_48);
*(dac_cfg + COMPONENT_START_OFFSET + PHASE_OFFSET + COMPONENT_OFFSET*1 + CHANNEL_OFFSET*channel) = register_value;
return 0;
}

int setArbitraryWaveform(float* values, int channel) {
uint32_t *awg_cfg = NULL;
if (channel == 0) {
Expand Down Expand Up @@ -1392,6 +1425,10 @@ rp_calib_params_t getDefaultCalib(){
calib.adc_ch1_offs = 0.0;
calib.adc_ch2_fs = 1.0/8192.0;
calib.adc_ch2_offs = 0.0;
calib.dac_ch1_lower = -1.0;
calib.dac_ch1_upper = 1.0;
calib.dac_ch2_lower = -1.0;
calib.dac_ch2_upper = 1.0;
return calib;
}

Expand Down Expand Up @@ -1440,14 +1477,37 @@ int calib_validate(rp_calib_params_t * calib_params) {
calib_params->dac_ch2_offs = def.dac_ch2_offs;
calib_params->set_flags &= ~(1 << 7);
}

// DAC Limits
if (useDefault || !(calib_params->set_flags & (1 << 8))) {
calib_params->dac_ch1_lower = def.dac_ch1_lower;
calib_params->set_flags &= ~(1 << 8);
}
if (useDefault || !(calib_params->set_flags & (1 << 9))) {
calib_params->dac_ch1_upper = def.dac_ch1_upper;
calib_params->set_flags &= ~(1 << 9);
}
if (useDefault || !(calib_params->set_flags & (1 << 10))) {
calib_params->dac_ch2_lower = def.dac_ch2_lower;
calib_params->set_flags &= ~(1 << 10);
}
if (useDefault || !(calib_params->set_flags & (1 << 11))) {
calib_params->dac_ch2_upper = def.dac_ch2_upper;
calib_params->set_flags &= ~(1 << 11);
}

return 0;
}

int calib_apply() {
setCalibDACScale(calib.dac_ch1_fs, 0);
setCalibDACOffset(calib.dac_ch1_offs, 0);
setCalibDACLowerLimit(calib.dac_ch1_lower, 0);
setCalibDACUpperLimit(calib.dac_ch1_upper, 0);
setCalibDACScale(calib.dac_ch2_fs, 1);
setCalibDACOffset(calib.dac_ch2_offs, 1);
setCalibDACLowerLimit(calib.dac_ch2_lower, 1);
setCalibDACUpperLimit(calib.dac_ch2_upper, 1);
return 0;
}

Expand Down Expand Up @@ -1511,6 +1571,36 @@ int calib_setDACScale(rp_calib_params_t * calib_params, float value, int channel
return 0;
}

int calib_setDACLowerLimit(rp_calib_params_t * calib_params, float value, int channel) {
if (channel < 0 || channel > 1) {
return -3;
}
if (channel == 0) {
calib_params->dac_ch1_lower = value;
calib_params->set_flags |= (1 << 8);
}
else if (channel == 1) {
calib_params->dac_ch2_lower = value;
calib_params->set_flags |= (1 << 10);
}
return 0;
}

int calib_setDACUpperLimit(rp_calib_params_t * calib_params, float value, int channel) {
if (channel < 0 || channel > 1) {
return -3;
}
if (channel == 0) {
calib_params->dac_ch1_upper = value;
calib_params->set_flags |= (1 << 9);
}
else if (channel == 1) {
calib_params->dac_ch2_upper = value;
calib_params->set_flags |= (1 << 11);
}
return 0;
}


void calib_SetToZero() {
calib = getDefaultCalib();
Expand Down
12 changes: 10 additions & 2 deletions src/lib/rp-daq-lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
#define DIO_IN 1
#define DIO_OUT 0

#define CALIB_VERSION 1
#define CALIB_VERSION 2

extern bool verbose;

Expand Down Expand Up @@ -96,6 +96,8 @@ extern int getSignalType(int, int);
extern int setSignalType(int, int, int);
extern int setCalibDACScale(float, int);
extern int setCalibDACOffset(float, int);
extern int setCalibDACLowerLimit(float, int);
extern int setCalibDACUpperLimit(float, int);
extern int setArbitraryWaveform(float*, int);
//extern int getRampingPeriod(int);

Expand Down Expand Up @@ -200,7 +202,7 @@ extern void stopTx();
typedef struct {
char id[3+1];
int version;
uint8_t set_flags;
uint16_t set_flags;
float adc_ch1_fs;
float adc_ch1_offs;
float adc_ch2_fs;
Expand All @@ -209,6 +211,10 @@ typedef struct {
float dac_ch1_offs;
float dac_ch2_fs;
float dac_ch2_offs;
float dac_ch1_lower;
float dac_ch1_upper;
float dac_ch2_lower;
float dac_ch2_upper;
} rp_calib_params_t;

extern int calib_Init();
Expand All @@ -220,6 +226,8 @@ extern int calib_setADCOffset(rp_calib_params_t * calib_params, float value, int
extern int calib_setADCScale(rp_calib_params_t * calib_params, float value, int channel);
extern int calib_setDACOffset(rp_calib_params_t * calib_params, float value, int channel);
extern int calib_setDACScale(rp_calib_params_t * calib_params, float value, int channel);
extern int calib_setDACLowerLimit(rp_calib_params_t * calib_params, float value, int channel);
extern int calib_setDACUpperLimit(rp_calib_params_t * calib_params, float value, int channel);

extern rp_calib_params_t calib_GetParams();
extern rp_calib_params_t calib_GetDefaultCalib();
Expand Down
Loading
Loading