Skip to content

Commit

Permalink
Merge pull request #72 from tknopp/nh/signalLimits
Browse files Browse the repository at this point in the history
Saturate fast DAC Signals with calibrated upper and lower limits
  • Loading branch information
nHackel authored Dec 1, 2023
2 parents daa96f8 + 4441f6a commit 95aa670
Show file tree
Hide file tree
Showing 8 changed files with 281 additions and 8 deletions.
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

0 comments on commit 95aa670

Please sign in to comment.