C library

The C library (found in cmirp.h, cmirp.c files) is an interface to all the FPGA functionality and all the SPI communication with the additional electronic boards. These functions are also used in all the test applications and the server (gwyhwserver). Note that some of the function parameters should match the physical hardware settings (e.g. the jumpers on electronic boards). At the server level this is done using the hwserver.ini file, however when the C library is used for anything else (as in the test files provided in the same directory as the server), this has to be taken into account.

Here the library API is described:

int librp_Init(librpSet *rpset, int hrdac_regime, int hrdac1_range, int hrdac2_range, int hrdac3_range, int input_range1, int input_range2, int dds1_range, int dds2_range, int oversampling, int rp1_input_hv, int rp2_input_hv, int rp_bare_output, int rp_bare_input);

This function initializes all the functions and connections, and sets all the default values. Parameter hrdac_regime controls how the 20bit DACs will be used (0: entirely from FPGA, 1: entirely from CPU). The next three parameters set the 20bit output range and should match the jumpers on the board (LIBRP_HRDAC_RANGE_FULL: ±10 V,  LIBRP_HRDAC_RANGE_SMALL: 0–10V).  Parameters input_range1 and input_range2 are related to RP inputs: 0 means ±1V operation, 1 is ±10 V. Some of these settings are turned on when the SetState command is issued. Parameters dds1_range and dds2_range can be used to override the default range of synthesized harmonic signal coming out of the lock-in. If set to 1, the amplitude range is only 0.5 V and the signal is shifted towards positive values. This can be useful when output should go directly to some piezo amplifier. Otherwise the full range ±1 V is used, which is the default behavior. Oversampling is applied to ADS8598H ADCs connected via SPI communication. Allowed values range from 0 (no averaging) to 6 (64 values are averaged), which is also the default value. See the ADC datasheet for more information.

Parameter rp1_input_hv and rp1_input_hv should be set to 1 if the fast ADC jumpers on RP are on HV range. Parameter rp_bare_output should be set to 1 if we don’t use the auxiliary amplifiers to convert the bare RP outputs from ±1 V to ±10 V. Similarly, parameter rp_bare_input should be used only if the inputs are connected directly to fast RP ADC.

int librp_LoadCalData(librpSet *rpset, double rpadc1_bare_lv_offset, double rpadc1_bare_lv_slope, double rpadc1_bare_hv_offset, double rpadc1_bare_hv_slope, double rpadc2_bare_lv_offset, double rpadc2_bare_lv_slope, double rpadc2_bare_hv_offset, double rpadc2_bare_hv_slope, double rpadc1_divhigh_lv_offset, double rpadc1_divhigh_lv_slope, double rpadc1_divhigh_hv_offset, double rpadc1_divhigh_hv_slope, double rpadc1_divlow_lv_offset, double rpadc1_divlow_lv_slope, double rpadc1_divlow_hv_offset, double rpadc1_divlow_hv_slope, double rpadc2_divhigh_lv_offset, double rpadc2_divhigh_lv_slope, double rpadc2_divhigh_hv_offset, double rpadc2_divhigh_hv_slope, double rpadc2_divlow_lv_offset, double rpadc2_divlow_lv_slope, double rpadc2_divlow_hv_offset, double rpadc2_divlow_hv_slope);

Sets the conversion factors between fast RP inputs and real values for all the potential combinations of input settings. This includes LV and HV option on the RP inputs, use of 1:10 divider on the auxiliary board, use of this board without division and use of bare inputs without board. The used equation has form: real_world_value = (integer_value + offset)*slope.

int librp_SetInputRange(librpSet *rpset, int input1_range, int input2_range)

Changes the input range settings (see librp_Init).

int librp_SetDDSRange(librpSet *rpset, int dds1_range, int dds2_range)

Changes the DDS range settings (see librp_Init).

int librp_SetOversampling(librpSet *rpset, int oversampling)

Changes the oversampling settings (see librp_Init).

int librp_Close (librpSet *rpset)

Stops all the functions and closes all connections.

int librp_ReadADC (librpSet *rpset, double *adc1, double *adc2)

Reads actual FPGA raw ADC values for the two simultaneous high-speed inputs, converted from raw values to the ±1V input range.

int librp_ReadResults (librpSet *rpset, double *error, double *dac, int raw)

Reads actual main FPGA feedback loop results. Meaning of the error signal depends on the feedback loop regime. Values are converted from FPGA numbers depending on the regime of operation, unless the raw option is set. Note that the result value (dac) can be in practice routed somewhere else than the particular channel dac output, depending on mode of operation. If a 20bit external DAC is connected and the zpiezo_hrdac option is set, librp_ReadZSlow provides the correct dac value.

int librp_ReadLockin (librpSet *rpset, int channel, double *amplitude, double *phase)

Reads actual FPGA lock-in results for  the selected channel, regardless if there is anything generated in that channel or if it has any meaning at the moment.

int librp_ReadLockinAxes  (librpSet *rpset, int channel, double *x, double *y);

Reads the sine/cosine demodulation data from a lockin.

int librp_ReadHRDAC (librpSet *rpset, double *zslow)

Reads the FPGA based z value that goes to 20 bit DAC for z axis, if requested so during the init phase. In contrast to ReadResults dac value, which is scaled for the RP 14 bit output, this value has higher bit depth.

int librp_ReadPLLResult (librpSet *rpset, double *pllresult, double *ampresult)

Reads actual FPGA value of PLL results, used in FM mode (tracked frequency and amplitude).

int librp_ReadDebug (librpSet *rpset, double *debug)

Reads actual FPGA debug value, this might be whatever is connected to it on the FPGA side. It is not intended for general use.

int librp_SetState(librpSet *rpset, int state, int feedback, int out1, int out2, int outhr, int swap_in, int swap_out, int pidskip)

Sets the FPGA feedback loop, feedback loop status (on/off) and other parameters: output channels for two fast RP outputs and for the 20bit DAC if enabled (e.g. excitation, dac value, pid result, see cmirp.h for definition) and input/output signal swaps. Pidskip can be used to slow down the feedback loop (0: 125 MHz, 1: 1 MHz, 2: 120 kHz, 3: 15 kHz).

int librp_SetFeedback(librpSet *rpset, int feedback)

Convenience function that calls librp_SetState with actual parameters except feedback, to switch it on or off.

int librp_SetSignalProcessing(librpSet *rpset, int channel, int decimation, int loopback, int hr, int phaseshift, int debugsource, int filter_phase, int nwaves, int lfr, int intosc, int loopbackshift)

Sets different parameters of a channel. Parameter decimation sets the FPGA IIR filter for the selected channel. Decimation=0 means that the filter is switched off, the reasonable values are 1-12. Parameter loopback allows the use of an internal value (e.g. output of another calculation) as an input to the lockin. Which parameter is used internally is controlled by the SetState() command. Parameter hr increases the resolution of the lockin about 64 times, at costs of bad operation for higher voltages and lower frequencies. Parameter debugsource passes either sine or cosine signal to debug output of the lockin. Filter_phase adds a simple IIR low pass filter at about 4 kHz to phase output of the lock-in. Parameter nwaves determines from how many individual waves each lock-in output is calculated, 0–5 means 1–32 waves (2N). Parameter lfr sets the generator range: 0 means full range (0-2 MHz, about 0.02), 1 means the limited range. Parameter intosc asks the lock-in related to this channel to use auxiliary signal generator (see SetAuxGen) as the reference frequency for lock-in detection, instead of its own frequency set by SetGen (that is then used only for output). Parameter loopbackshift (0-15) controls the bitshift of loopback internal signal on the input to filtering module - the higher the value is the more is the passed value divided.

int librp_SetGen (librpSet *rpset, int channel, double frequency, double amplitude, double offset)

Sets the FPGA frequency and amplitude of the lock-in frequency generator. Frequency (in Hertz) can be set in the range from 500 Hz to 1990000 Hz, amplitude is in Volts and its range is ±10 V. Depending on the feedback loop regime this value is output to the DAC or not. Offset is added to the value (provided in Volts, range is ±10 V).

int librp_SetSetpoint (librpSet *rpset, double setpoint, int raw)

Sets the FPGA setpoint for the main feedback loop. The value is converted to appropriate FPGA numbers depending on the regime of operation, unless a raw option is set.

int librp_SetPid  (librpSet *rpset, double p, double i, double d, int errorshift)

Sets the FPGA PID parameters for the main feedback loop. Parameters can be in range 0-1, higher value typically means faster response. Note that changing PID parameters on the fly might lead to some interrupted operation, which should be avoided - a possible workaround is to stop the feedback before setting PID values and to start it after that again. Parameter errorshift performs a bit shift of the error signal internally in the feedback loop.

int librp_SetPidOffset (librpSet *rpset, double value)

Sets the offset of zpiezo, i.e. value that is added to the feedback loop output.

int librp_GetPidOffset (librpSet *rpset, double value)

Gets the last set value of piezo offset.

int librp_SetKPFM (librpSet *rpset, int mode, double frequency, double amplitude, double p, double i, double d, double offset, int loopback, int loopbackshift)

Sets all the parameters of KPFM operation from one place, calling different functions to set the desired frequency, amplitude, offset. All this can be done also manually. Modes are defined in cmirp.h and can be either manual (only setting the voltage) or “kpfm”, with a feedback loop. In the FM regime the phase output of lock-in1 is driven to lock-in2 (parameter loopback in SetSignalProcessing of channel 2, here set for convenience as loopback and loopbackshift parameter). Note that using KPFM requires use of external 20bit z-piezo, in order to free the 14bit output for KPFM operation.

int librp_SetDAC (librpSet *rpset, int channel, double value)

Sets the FPGA high speed DAC outputs directly. This is done only when the regime and feedback loop state allows it. Range is ±1V. If this is set up during the init phase, the channel 2 output can also be set via 20bit DAC using this function, in this case the range is 0-10 V or ±10 V (also set in librp_Init function).

int librp_SetHRDAC (librpSet *rpset, double value)

Sets the value for the 20 bit DAC connected to the FPGA, the range is the same as for the librp_SetDAC.

int librp_SetPLL (librpSet *rpset, int on, int amon, double phase, double amplitude, double p, double i, double ap, double ai, double ad, int phase_limit, int frequency_limit, int pllskip, int pll_input)

Sets the PLL operation. Phase is the setpoint value (in radians), p and i are parameters of the feedback loop, which is switched on and off using the on value. The amplitude stabilisation can be switched using the “amon” parameter and second set of PID loop parameters. Settable phase limit (integer values 0-7 correspond to about 1/32 to full scale) can be used prior to FM feedback loop application, as well as maximum frequency shift limit (integer values 0-7 correspond to about 7.5, 15, 30, 60, 120, 240 and 480 Hz).  Pllskip is the slowdown factor for the PLL feedback loop, having the same meaning as for the main PID.

int librp_DPinSetState (librpSet *rpset, int pin, int on)

Sets the FPGA digital output pin on (high) or off (low). Pins are numbered 0-15, representing first dio_n [0-7] and then dio_p [8-15] on the Red Pitaya extension connector. Note that when the whole electronics is used (including the generation and data acquisition framework), the pins 0-15 should not be controlled by the user as they serve for driving the additional DA and AD converters.

int librp_SPICycle (librpSet *rpset, double hrdac1, double hrdac2, double hrdac3, double *lrdac, double *adc, int read_adc1, int read_adc2, int mux1, int mux2)

Runs the whole SPI communication cycle: three high resolution DAC values hrdac1, hrdac2 and hrdac3 are set (range is ±10 V) , sixteen low resolution DAC values are set, provided by array lrdac[16] (range is +-10 V) and sixteen ADCs are read and stored to adc[16] array (range is ±10 V). The ADC readout can be further tuned by reading the first eight channels, the second eight channels, or all. All the DAC values are set only if they differ from previous settings. Mux1 and mux2 values control the multiplexers (values in the range 0-15), i.e. they control which analog signal is connected to Red Pitaya’s input1 or input2, respectively.