moved libs to the lib directory
This commit is contained in:
795
lib/x502/x502api_config.c
Normal file
795
lib/x502/x502api_config.c
Normal file
@ -0,0 +1,795 @@
|
||||
#include "x502api_private.h"
|
||||
#include "x502_fpga_regs.h"
|
||||
|
||||
#define SYNC_FREQ_CODE(mode) ((mode == X502_SYNC_DI_SYN2_RISE) ? X502_SYNC_DI_SYN1_FALL : \
|
||||
(mode == X502_SYNC_DI_SYN1_FALL) ? X502_SYNC_DI_SYN2_RISE : mode)
|
||||
|
||||
#define CHECK_SYNC_MODE(mode) (((mode)) != X502_SYNC_INTERNAL) \
|
||||
&& ((mode)!=X502_SYNC_EXTERNAL_MASTER) \
|
||||
&& ((mode)!=X502_SYNC_DI_SYN1_RISE) \
|
||||
&& ((mode)!=X502_SYNC_DI_SYN2_RISE) \
|
||||
&& ((mode)!=X502_SYNC_DI_SYN1_FALL) \
|
||||
&& ((mode)!=X502_SYNC_DI_SYN2_FALL) \
|
||||
? X502_ERR_INVALID_SYNC_MODE : X502_ERR_OK
|
||||
|
||||
/** Максимальное значения частоты АЦП для варианта E16*/
|
||||
#define E16_ADC_FREQ_MAX 1000000
|
||||
/** Максимальное значения частоты DIN для варианта E16*/
|
||||
#define E16_DIN_FREQ_MAX 1000000
|
||||
/** Максимальное значения частоты OUT для варианта E16*/
|
||||
#define E16_OUT_FREQ_MAX 1000000
|
||||
|
||||
static const uint16_t f_regadd_k[X502_ADC_RANGE_CNT] = {X502_REGS_IOARITH_K10,
|
||||
X502_REGS_IOARITH_K5,
|
||||
X502_REGS_IOARITH_K2,
|
||||
X502_REGS_IOARITH_K1,
|
||||
X502_REGS_IOARITH_K05,
|
||||
X502_REGS_IOARITH_K02};
|
||||
|
||||
static const uint16_t f_regadd_offs[X502_ADC_RANGE_CNT] = {X502_REGS_IOARITH_B10,
|
||||
X502_REGS_IOARITH_B5,
|
||||
X502_REGS_IOARITH_B2,
|
||||
X502_REGS_IOARITH_B1,
|
||||
X502_REGS_IOARITH_B05,
|
||||
X502_REGS_IOARITH_B02};
|
||||
|
||||
|
||||
static uint32_t f_get_out_freq_div_min(double ref_freq) {
|
||||
return ref_freq > X502_OUT_FREQ_REF_LF_VAL ? X502_OUT_FREQ_DIV_MIN : X502_OUT_FREQ_DIV_MIN_REF_LF;
|
||||
}
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetLChannel(t_x502_hnd hnd, uint32_t lch, uint32_t phy_ch,
|
||||
uint32_t mode, uint32_t range, uint32_t avg) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
/* Для измерения собственного нуля номер канала не имеет значения */
|
||||
if (mode == X502_LCH_MODE_ZERO)
|
||||
phy_ch = 0;
|
||||
|
||||
if ((mode != X502_LCH_MODE_COMM) && (mode != X502_LCH_MODE_DIFF) &&
|
||||
(mode != X502_LCH_MODE_ZERO)) {
|
||||
err = X502_ERR_INVALID_LCH_MODE;
|
||||
} else if ((phy_ch >= X502_ADC_COMM_CH_CNT) ||
|
||||
((mode == X502_LCH_MODE_DIFF) && (phy_ch >= X502_ADC_DIFF_CH_CNT))) {
|
||||
err = X502_ERR_INVALID_LCH_PHY_NUMBER;
|
||||
} else if (range >= X502_ADC_RANGE_CNT) {
|
||||
err = X502_ERR_INVALID_LCH_RANGE;
|
||||
} else if (avg > X502_LCH_AVG_SIZE_MAX) {
|
||||
err = X502_ERR_INVALID_LCH_AVG_SIZE;
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
hnd->set.lch[lch].ch = phy_ch;
|
||||
hnd->set.lch[lch].range = range;
|
||||
hnd->set.lch[lch].mode = mode;
|
||||
hnd->set.lch[lch].avg = avg;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetLChannelCount(t_x502_hnd hnd, uint32_t lch_cnt) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
if (lch_cnt > X502_LTABLE_MAX_CH_CNT) {
|
||||
err = X502_ERR_INVALID_LTABLE_SIZE;
|
||||
} else if (x502_is_E16(hnd) && lch_cnt > E16_LTABLE_MAX_CH_CNT) {
|
||||
err = X502_ERR_INVALID_LTABLE_SIZE;
|
||||
} else {
|
||||
hnd->set.lch_cnt = lch_cnt;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_GetLChannelCount(t_x502_hnd hnd, uint32_t* lch_cnt) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (lch_cnt==NULL))
|
||||
err = X502_ERR_INVALID_POINTER;
|
||||
|
||||
if (!err)
|
||||
*lch_cnt = hnd->set.lch_cnt;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetAdcFreqDivider(t_x502_hnd hnd, uint32_t adc_freq_div) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
if ((adc_freq_div==0) ||
|
||||
(x502_is_E16(hnd) && adc_freq_div > E16_ADC_FREQ_DIV_MAX) ||
|
||||
(!x502_is_E16(hnd) && adc_freq_div > X502_ADC_FREQ_DIV_MAX)) {
|
||||
err = X502_ERR_INVALID_ADC_FREQ_DIV;
|
||||
} else {
|
||||
hnd->set.adc_freq_div = adc_freq_div;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetAdcInterframeDelay(t_x502_hnd hnd, uint32_t delay) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err && (delay > X502_ADC_INTERFRAME_DELAY_MAX))
|
||||
err = X502_ERR_INVALID_INTERFRAME_DELAY;
|
||||
|
||||
if (!err) {
|
||||
hnd->set.adc_frame_delay = delay;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetDinFreqDivider(t_x502_hnd hnd, uint32_t din_freq_div) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
if ((din_freq_div==0) ||
|
||||
(x502_is_E16(hnd) && din_freq_div > E16_DIN_FREQ_DIV_MAX) ||
|
||||
(!x502_is_E16(hnd) && din_freq_div > X502_DIN_FREQ_DIV_MAX)) {
|
||||
err = X502_ERR_INVALID_ADC_FREQ_DIV;
|
||||
} else {
|
||||
hnd->set.din_freq_div = din_freq_div;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetOutFreqDivider(t_x502_hnd hnd, uint32_t out_freq_div) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
/* Проверяем, поддерживается ли возможность установить значение, отличное от стандартного */
|
||||
if (out_freq_div != X502_OUT_FREQ_DIV_DEFAULT) {
|
||||
err = X502_CheckFeature(hnd, X502_FEATURE_OUT_FREQ_DIV);
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
double ref_freq;
|
||||
X502_GetRefFreqValue(hnd, &ref_freq);
|
||||
if ((out_freq_div < f_get_out_freq_div_min(ref_freq)) ||
|
||||
(x502_is_E16(hnd) && out_freq_div > E16_OUT_FREQ_DIV_MAX) ||
|
||||
(!x502_is_E16(hnd) && out_freq_div > X502_OUT_FREQ_DIV_MAX)) {
|
||||
err = X502_ERR_INVALID_OUT_FREQ_DIV;
|
||||
} else {
|
||||
hnd->set.out_freq_div = out_freq_div;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetMode(t_x502_hnd hnd, uint32_t mode) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err && (mode==X502_MODE_DSP) &&
|
||||
!(hnd->info.devflags & X502_DEVFLAGS_BF_PRESENT)) {
|
||||
err = X502_ERR_BF_NOT_PRESENT;
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
uint32_t val;
|
||||
err = hnd->iface_hnd->fpga_reg_read(hnd, X502_REGS_BF_CTL, &val);
|
||||
if (!err) {
|
||||
val &= ~(X502_REGBIT_BF_CTL_CLK_DIV_Msk | X502_REGBIT_BF_CTL_DBG_MODE_Msk | X502_REGBIT_BF_CTL_DSP_MODE_Msk);
|
||||
if (mode==X502_MODE_DSP) {
|
||||
/* в DSP режиме сброс должен быть снят с blackfin, иначе не будут работать
|
||||
команды по HostDMA */
|
||||
val |= X502_REGBIT_BF_CTL_DSP_MODE_Msk | X502_REGBIT_BF_CTL_BF_RESET_Msk;
|
||||
} else if (mode==X502_MODE_DEBUG) {
|
||||
val |= X502_REGBIT_BF_CTL_DBG_MODE_Msk;
|
||||
} else if (mode!=X502_MODE_FPGA) {
|
||||
err = X502_ERR_INVALID_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err)
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_BF_CTL, val);
|
||||
|
||||
/* при переходе в режим DSP сбрасываем автомат HDMA */
|
||||
if (!err && (mode==X502_MODE_DSP))
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_BF_CMD, X502_BF_CMD_HDMA_RST);
|
||||
|
||||
if (!err)
|
||||
hnd->mode = mode;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_GetMode(t_x502_hnd hnd, uint32_t* mode) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (mode==NULL))
|
||||
err = X502_ERR_INVALID_POINTER;
|
||||
|
||||
if (!err) {
|
||||
*mode = hnd->mode;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#define IS_E16_FREQ(hnd, ref_freq) ((hnd && x502_is_E16(hnd)) || (uint32_t)ref_freq == E16_REF_FREQ_48000KHZ)
|
||||
|
||||
X502_EXPORT(int32_t) X502_CalcAdcFreq2(t_x502_hnd hnd, double ref_freq, uint32_t lch_cnt, double *f_acq,
|
||||
double *f_frame, uint32_t *adc_freq_div, uint32_t *adc_frame_delay) {
|
||||
int32_t err = (f_acq==NULL) ? X502_ERR_INVALID_POINTER : X502_ERR_OK;
|
||||
if (err == X502_ERR_OK) {
|
||||
uint32_t cur_adc_freq_div, cur_frame_delay = 0;
|
||||
uint32_t div_max = X502_ADC_FREQ_DIV_MAX;
|
||||
|
||||
double set_freq = *f_acq;
|
||||
if (set_freq <= 0) {
|
||||
if (IS_E16_FREQ(hnd, ref_freq)) {
|
||||
set_freq = E16_ADC_FREQ_DEFAULT;
|
||||
} else {
|
||||
set_freq = ref_freq;
|
||||
}
|
||||
}
|
||||
if (IS_E16_FREQ(hnd, ref_freq)) {
|
||||
div_max = E16_ADC_FREQ_DIV_MAX;
|
||||
if (set_freq > E16_ADC_FREQ_MAX) {
|
||||
set_freq = E16_ADC_FREQ_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
cur_adc_freq_div = (uint32_t)(ref_freq/set_freq+0.49);
|
||||
if (cur_adc_freq_div == 0)
|
||||
cur_adc_freq_div = 1;
|
||||
if (cur_adc_freq_div > div_max)
|
||||
cur_adc_freq_div = div_max;
|
||||
set_freq = ref_freq/cur_adc_freq_div;
|
||||
|
||||
*f_acq = set_freq;
|
||||
|
||||
if (f_frame==NULL) {
|
||||
cur_frame_delay = 0;
|
||||
} else {
|
||||
if (lch_cnt == 0)
|
||||
lch_cnt = 1;
|
||||
|
||||
if (*f_frame <= 0) {
|
||||
cur_frame_delay = 0;
|
||||
} else {
|
||||
int32_t frame_div = (int32_t)((ref_freq/(*f_frame)
|
||||
- lch_cnt*ref_freq/set_freq)+0.49);
|
||||
|
||||
cur_frame_delay = frame_div <=0 ? 0 :
|
||||
frame_div > X502_ADC_INTERFRAME_DELAY_MAX ?
|
||||
X502_ADC_INTERFRAME_DELAY_MAX : frame_div;
|
||||
}
|
||||
*f_frame = 1./(lch_cnt/set_freq +
|
||||
cur_frame_delay/ref_freq);
|
||||
}
|
||||
|
||||
if (adc_freq_div != NULL)
|
||||
*adc_freq_div = cur_adc_freq_div;
|
||||
if (adc_frame_delay != NULL)
|
||||
*adc_frame_delay = cur_frame_delay;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_CalcAdcFreq(double ref_freq, uint32_t lch_cnt, double *f_acq,
|
||||
double *f_frame, uint32_t *adc_freq_div, uint32_t *adc_frame_delay) {
|
||||
return X502_CalcAdcFreq2(NULL, ref_freq, lch_cnt, f_acq, f_frame, adc_freq_div, adc_frame_delay);
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetAdcFreq(t_x502_hnd hnd, double *f_acq, double *f_frame) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
double ref_freq;
|
||||
X502_GetRefFreqValue(hnd, &ref_freq);
|
||||
err = X502_CalcAdcFreq2(hnd, ref_freq, hnd->set.lch_cnt, f_acq, f_frame,
|
||||
&hnd->set.adc_freq_div, &hnd->set.adc_frame_delay);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_GetAdcFreq(t_x502_hnd hnd, double *f_acq, double *f_frame) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (f_acq == NULL) && (f_frame==NULL))
|
||||
err = X502_ERR_INVALID_POINTER;
|
||||
|
||||
if (!err) {
|
||||
double ref_freq, set_freq;
|
||||
|
||||
X502_GetRefFreqValue(hnd, &ref_freq);
|
||||
|
||||
set_freq = ref_freq/hnd->set.adc_freq_div;
|
||||
if (f_acq!=NULL) {
|
||||
*f_acq = set_freq;
|
||||
}
|
||||
|
||||
if (f_frame!=NULL) {
|
||||
*f_frame = 1./(hnd->set.lch_cnt/set_freq +
|
||||
hnd->set.adc_frame_delay/ref_freq);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_CalcDinFreq2(t_x502_hnd hnd, double ref_freq, double *f_din, uint32_t *result_freq_div) {
|
||||
int32_t err = f_din==NULL ? X502_ERR_INVALID_POINTER : X502_ERR_OK;
|
||||
if (err == X502_ERR_OK) {
|
||||
uint32_t freq_div;
|
||||
double set_freq = *f_din;
|
||||
uint32_t div_max = X502_DIN_FREQ_DIV_MAX;
|
||||
|
||||
if (set_freq<=0) {
|
||||
if (IS_E16_FREQ(hnd, ref_freq)) {
|
||||
set_freq = E16_DIN_FREQ_DEFAULT;
|
||||
} else {
|
||||
set_freq = ref_freq;
|
||||
}
|
||||
}
|
||||
if (IS_E16_FREQ(hnd, ref_freq)) {
|
||||
div_max = E16_DIN_FREQ_DIV_MAX;
|
||||
if (set_freq > E16_DIN_FREQ_MAX) {
|
||||
set_freq = E16_DIN_FREQ_MAX;
|
||||
}
|
||||
}
|
||||
freq_div = (uint32_t)(ref_freq/set_freq+0.49);
|
||||
if (freq_div == 0)
|
||||
freq_div = 1;
|
||||
if (freq_div > div_max)
|
||||
freq_div = div_max;
|
||||
set_freq = ref_freq/freq_div;
|
||||
*f_din = set_freq;
|
||||
|
||||
if (result_freq_div != NULL)
|
||||
*result_freq_div = freq_div;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_CalcDinFreq(double ref_freq, double *f_din, uint32_t *result_freq_div) {
|
||||
return X502_CalcDinFreq2(NULL, ref_freq, f_din, result_freq_div);
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetDinFreq(t_x502_hnd hnd, double *f_din) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
if (!err) {
|
||||
double ref_freq;
|
||||
X502_GetRefFreqValue(hnd, &ref_freq);
|
||||
err = X502_CalcDinFreq2(hnd, ref_freq, f_din, &hnd->set.din_freq_div);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_CalcOutFreq2(t_x502_hnd hnd, double ref_freq, double *f_dout, uint32_t *result_freq_div) {
|
||||
int32_t err = f_dout==NULL ? X502_ERR_INVALID_POINTER : X502_ERR_OK;
|
||||
if (err == X502_ERR_OK) {
|
||||
const uint32_t out_div_min = f_get_out_freq_div_min(ref_freq);
|
||||
uint32_t out_freq_div;
|
||||
uint32_t div_max = X502_OUT_FREQ_DIV_MAX;
|
||||
|
||||
|
||||
double set_freq = *f_dout;
|
||||
if (set_freq <= 0) {
|
||||
if (IS_E16_FREQ(hnd, ref_freq)) {
|
||||
set_freq = E16_OUT_FREQ_DEFAULT;
|
||||
} else {
|
||||
set_freq = ref_freq;
|
||||
}
|
||||
}
|
||||
if (IS_E16_FREQ(hnd, ref_freq)) {
|
||||
div_max = E16_OUT_FREQ_DIV_MAX;
|
||||
if (set_freq > E16_OUT_FREQ_MAX) {
|
||||
set_freq = E16_OUT_FREQ_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
out_freq_div = (uint32_t)(ref_freq/set_freq+0.49);
|
||||
if (out_freq_div < out_div_min)
|
||||
out_freq_div = out_div_min;
|
||||
if (out_freq_div > div_max)
|
||||
out_freq_div = div_max;
|
||||
|
||||
set_freq = ref_freq/out_freq_div;
|
||||
*f_dout = set_freq;
|
||||
|
||||
if (result_freq_div != NULL)
|
||||
*result_freq_div = out_freq_div;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_CalcOutFreq(double ref_freq, double *f_dout, uint32_t *result_freq_div) {
|
||||
return X502_CalcOutFreq2(NULL, ref_freq, f_dout, result_freq_div);
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetOutFreq(t_x502_hnd hnd, double *f_dout) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
if (!err && (f_dout==NULL))
|
||||
err = X502_ERR_INVALID_POINTER;
|
||||
|
||||
if (!err) {
|
||||
double ref_freq;
|
||||
|
||||
X502_GetRefFreqValue(hnd, &ref_freq);
|
||||
/* Если не поддерживается возможность установки нестандартного делителя, то
|
||||
всегда устанавливаем стандартный */
|
||||
if (X502_CheckFeature(hnd, X502_FEATURE_OUT_FREQ_DIV) != X502_ERR_OK) {
|
||||
hnd->set.out_freq_div = X502_OUT_FREQ_DIV_DEFAULT;
|
||||
*f_dout = ref_freq/hnd->set.out_freq_div;
|
||||
} else {
|
||||
err = X502_CalcOutFreq2(hnd, ref_freq, f_dout, &hnd->set.out_freq_div);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetRefFreq(t_x502_hnd hnd, uint32_t freq) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
if (x502_is_E16(hnd)) {
|
||||
// для E16 ref freq всегда 48 МГц
|
||||
hnd->set.ref_freq = E16_REF_FREQ_48000KHZ;
|
||||
} else {
|
||||
hnd->set.ref_freq = freq;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetExtRefFreqValue(t_x502_hnd hnd, double freq) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
if (!err)
|
||||
hnd->set.ext_ref_freq = freq;
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetAdcSyncStartValue(t_x502_hnd hnd, uint32_t phy_ch, uint32_t mode, uint32_t range, double value) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
if (!err) {
|
||||
hnd->set.adc_sync_ch = phy_ch;
|
||||
hnd->set.adc_sync_range = range;
|
||||
hnd->set.adc_sync_mode = mode;
|
||||
hnd->set.adc_sync_val = value;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_GetRefFreqValue(t_x502_hnd hnd, double *freq) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
|
||||
if (!err) {
|
||||
if ((hnd->set.sync_mode == X502_SYNC_INTERNAL) ||
|
||||
!(hnd->set.ext_ref_freq > 0)) {
|
||||
*freq = hnd->set.ref_freq;
|
||||
} else {
|
||||
*freq = hnd->set.ext_ref_freq;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetSyncMode(t_x502_hnd hnd, uint32_t sync_mode) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
err = CHECK_SYNC_MODE(sync_mode);
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
hnd->set.sync_mode = sync_mode;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetSyncStartMode(t_x502_hnd hnd, uint32_t sync_start_mode) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
if (sync_start_mode==E16_SYNC_ADC_EDGE_RISE ||
|
||||
sync_start_mode==E16_SYNC_ADC_EDGE_FALL ||
|
||||
sync_start_mode==E16_SYNC_ADC_ABOVE_LEVEL ||
|
||||
sync_start_mode==E16_SYNC_ADC_BELOW_LEVEL) {
|
||||
if (x502_is_E16(hnd) == false) {
|
||||
// реализовано только в E16
|
||||
return X502_ERR_INVALID_SYNC_MODE;
|
||||
}
|
||||
} else {
|
||||
err = CHECK_SYNC_MODE(sync_start_mode);
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
hnd->set.sync_start_mode = sync_start_mode;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
uint32_t get_ltable_val(t_x502_hnd hnd, uint32_t phy_ch, uint32_t mode, uint32_t range, uint32_t avg) {
|
||||
uint32_t wrd = ((phy_ch & 0xF) << 3) | (range & 0x7);
|
||||
|
||||
if (mode == X502_LCH_MODE_ZERO) {
|
||||
wrd |= (3 << 7);
|
||||
} else if (mode == X502_LCH_MODE_COMM) {
|
||||
wrd |= (phy_ch & 0x10 ? 2 : 1) << 7;
|
||||
}
|
||||
|
||||
if (avg) {
|
||||
uint32_t avg_val = avg;
|
||||
if (avg_val > hnd->set.adc_freq_div)
|
||||
avg_val = hnd->set.adc_freq_div;
|
||||
wrd |= ((avg_val-1) & 0x7F) << 9;
|
||||
}
|
||||
return wrd;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_Configure(t_x502_hnd hnd, uint32_t flags) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
/* Проверяем правильность установленной опорной частоты.
|
||||
Для внутренней может быть только одно из двух значений,
|
||||
для внешней главное, чтобы не принимало требуемой */
|
||||
if ((hnd->set.sync_mode==X502_SYNC_INTERNAL)
|
||||
&& (hnd->set.ref_freq!=E16_REF_FREQ_48000KHZ)
|
||||
&& (hnd->set.ref_freq!=X502_REF_FREQ_2000KHZ)
|
||||
&&(hnd->set.ref_freq!=X502_REF_FREQ_1500KHZ)) {
|
||||
err = X502_ERR_INVALID_REF_FREQ;
|
||||
} else if (hnd->set.ext_ref_freq > 2000000) {
|
||||
err = X502_ERR_INVALID_REF_FREQ;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
if (hnd->mode == X502_MODE_FPGA) {
|
||||
uint32_t ch;
|
||||
/* записываем логическую таблицу */
|
||||
for (ch=0; (ch < hnd->set.lch_cnt) && !err; ch++) {
|
||||
uint32_t wrd = get_ltable_val(hnd, hnd->set.lch[ch].ch, hnd->set.lch[ch].mode, hnd->set.lch[ch].range, hnd->set.lch[ch].avg);
|
||||
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, (X502_REGS_IOHARD_LTABLE +
|
||||
hnd->set.lch_cnt - 1 - ch) & 0xFFFF, wrd);
|
||||
}
|
||||
if (!err) {
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_LCH_CNT,
|
||||
hnd->set.lch_cnt-1);
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_ADC_FREQ_DIV,
|
||||
hnd->set.adc_freq_div-1);
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOARITH_ADC_FREQ_DIV,
|
||||
hnd->set.adc_freq_div-1);
|
||||
}
|
||||
|
||||
|
||||
if (!err) {
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_ADC_FRAME_DELAY,
|
||||
hnd->set.adc_frame_delay);
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
// для варианта E16 ref_freq будет всегда 48000000
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_IO_MODE,
|
||||
(SYNC_FREQ_CODE(hnd->set.sync_mode) & 0x7)
|
||||
| ((hnd->set.sync_start_mode&0xF)<<3)
|
||||
| ((hnd->set.ref_freq==X502_REF_FREQ_2000KHZ ? X502_MODE_REF_FREQ_2000 :
|
||||
(hnd->set.ref_freq==X502_REF_FREQ_1500KHZ ? X502_MODE_REF_FREQ_1500: E16_MODE_REF_FREQ_48000)) << 7)
|
||||
| (((hnd->set.out_freq_div-1) & (x502_is_E16(hnd) ? 0x7FFF : 0x3FF))<<9));
|
||||
}
|
||||
|
||||
if (x502_is_E16(hnd)) {
|
||||
// старт по аналоговому сигналу реализован только в E16
|
||||
if (!err) {
|
||||
uint32_t wrd = get_ltable_val(hnd, hnd->set.adc_sync_ch, hnd->set.adc_sync_mode, hnd->set.adc_sync_range, 0);
|
||||
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOARITH_N_CHAN_SYN, wrd);
|
||||
}
|
||||
if (!err) {
|
||||
uint32_t threshold;
|
||||
threshold = hnd->set.adc_sync_val / hnd->set.f_scales[hnd->set.adc_sync_range] * E16_ADC_SCALE_CODE_MAX;
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOARITH_THRESHOLD, threshold);
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_DIGIN_FREQ_DIV,
|
||||
hnd->set.din_freq_div-1);
|
||||
}
|
||||
} else if (hnd->mode == X502_MODE_DSP) {
|
||||
uint32_t ch;
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_LCH_CNT, &hnd->set.lch_cnt, 1);
|
||||
for (ch=0; !err && (ch < hnd->set.lch_cnt); ch++) {
|
||||
uint32_t ch_par[] = {ch, hnd->set.lch[ch].ch,
|
||||
hnd->set.lch[ch].mode,
|
||||
hnd->set.lch[ch].range,
|
||||
hnd->set.lch[ch].avg > hnd->set.adc_freq_div ?
|
||||
hnd->set.adc_freq_div : hnd->set.lch[ch].avg} ;
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_LCH, ch_par,
|
||||
sizeof(ch_par)/sizeof(ch_par[0]));
|
||||
}
|
||||
if (!err) {
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_ADC_FREQ_DIV,
|
||||
&hnd->set.adc_freq_div, 1);
|
||||
}
|
||||
if (!err) {
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_ADC_FRAME_DELAY,
|
||||
&hnd->set.adc_frame_delay, 1);
|
||||
}
|
||||
if (!err) {
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_REF_FREQ_SRC,
|
||||
&hnd->set.ref_freq, 1);
|
||||
}
|
||||
if (!err) {
|
||||
uint32_t sync_code = SYNC_FREQ_CODE(hnd->set.sync_mode);
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_SYNC_MODE,
|
||||
&sync_code, 1);
|
||||
}
|
||||
if (!err) {
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_SYNC_START_MODE,
|
||||
&hnd->set.sync_start_mode, 1);
|
||||
}
|
||||
if (!err) {
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_DAC_FREQ_DIV,
|
||||
&hnd->set.out_freq_div, 1);
|
||||
}
|
||||
if (!err)
|
||||
{
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_DIN_FREQ_DIV,
|
||||
&hnd->set.din_freq_div, 1);
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
err = X502_BfExecCmd(hnd, L502_BF_CMD_CODE_CONFIGURE, 0, NULL,
|
||||
0, NULL, 0, X502_BF_CMD_DEFAULT_TOUT, NULL);
|
||||
}
|
||||
} else {
|
||||
err = X502_ERR_INVALID_MODE;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetAdcCoef(t_x502_hnd hnd, uint32_t range, double k, double offs) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
|
||||
if (!err && (hnd->flags & PRIV_FLAGS_STREAM_RUN))
|
||||
err = X502_ERR_STREAM_IS_RUNNING;
|
||||
|
||||
if (!err) {
|
||||
if (x502_is_E16(hnd)) {
|
||||
if (range >= E16_ADC_RANGE_CNT) {
|
||||
err = X502_ERR_INVALID_LCH_RANGE;
|
||||
}
|
||||
} else {
|
||||
if (range >= X502_ADC_RANGE_CNT) {
|
||||
err = X502_ERR_INVALID_LCH_RANGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
uint32_t kval = (uint32_t)(k*0x400000);
|
||||
uint32_t offs_val = (uint32_t)(-offs);
|
||||
|
||||
if (hnd->mode == X502_MODE_FPGA) {
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, f_regadd_k[range], kval);
|
||||
if (!err)
|
||||
err = hnd->iface_hnd->fpga_reg_write(hnd, f_regadd_offs[range], offs_val);
|
||||
} else if (hnd->mode == X502_MODE_DSP) {
|
||||
uint32_t wrds[3] = {range, kval, offs_val};
|
||||
err = x502_bf_set_par(hnd, L502_BF_PARAM_ADC_COEF, wrds, 3);
|
||||
} else {
|
||||
err = X502_ERR_INVALID_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
hnd->info.cbr.adc[range].k = k;
|
||||
hnd->info.cbr.adc[range].offs = offs;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_GetAdcCoef(t_x502_hnd hnd, uint32_t range, double* k, double* offs) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err) {
|
||||
if (range >= X502_ADC_RANGE_CNT) {
|
||||
err = X502_ERR_INVALID_LCH_RANGE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
*k = hnd->info.cbr.adc[range].k;
|
||||
*offs = hnd->info.cbr.adc[range].offs;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
X502_EXPORT(int32_t) X502_SetDacCoef(t_x502_hnd hnd, uint32_t ch, double k, double offs) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
|
||||
if (!err && (ch!=X502_DAC_CH1) && (ch!=X502_DAC_CH2)) {
|
||||
err = X502_ERR_INVALID_DAC_CHANNEL;
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
hnd->info.cbr.dac[ch].offs = offs;
|
||||
hnd->info.cbr.dac[ch].k = k;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
X502_EXPORT(int32_t) X502_GetDacCoef(t_x502_hnd hnd, uint32_t ch, double* k, double* offs) {
|
||||
int32_t err = X502_CHECK_HND_OPENED(hnd);
|
||||
if (!err && (ch!=X502_DAC_CH1) && (ch!=X502_DAC_CH2)) {
|
||||
err = X502_ERR_INVALID_DAC_CHANNEL;
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
if (offs!=NULL)
|
||||
*offs = hnd->info.cbr.dac[ch].offs;
|
||||
|
||||
if (k!=NULL)
|
||||
*k = hnd->info.cbr.dac[ch].k;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
Reference in New Issue
Block a user