Files
E502_ADC_BF_PC_companion/lib/x502/x502api_async.c

144 lines
5.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "x502api_private.h"
#include "ltimer.h"
uint32_t prepare_dac_wrd(t_x502_hnd hnd, double val, uint32_t flags, const t_x502_cbr_coef* coef);
X502_EXPORT(int32_t) X502_AsyncOutDac(t_x502_hnd hnd, uint32_t ch, double data, uint32_t flags) {
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.devflags & X502_DEVFLAGS_DAC_PRESENT))
err = X502_ERR_DAC_NOT_PRESENT;
if (!err) {
uint32_t wr_val = prepare_dac_wrd(hnd, data, flags, &hnd->info.cbr.dac[ch]);
if (ch==X502_DAC_CH1) {
wr_val |= X502_STREAM_OUT_WORD_TYPE_DAC1;
} else {
wr_val |= X502_STREAM_OUT_WORD_TYPE_DAC2;
}
if (hnd->mode == X502_MODE_FPGA) {
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_ASYNC_OUT, wr_val);
} else if (hnd->mode == X502_MODE_DSP) {
err = X502_BfExecCmd(hnd, L502_BF_CMD_CODE_ASYNC_OUT, ch==X502_DAC_CH1 ?
L502_BF_CMD_ASYNC_TYPE_DAC1 : L502_BF_CMD_ASYNC_TYPE_DAC2,
(uint32_t*)&wr_val, 1, NULL, 0, X502_BF_CMD_DEFAULT_TOUT, NULL);
} else {
err = X502_ERR_INVALID_MODE;
}
}
return err;
}
X502_EXPORT(int32_t) X502_AsyncOutDig(t_x502_hnd hnd, uint32_t val, uint32_t msk) {
int32_t err = X502_CHECK_HND_OPENED(hnd);
if (!err) {
if(hnd->mode == X502_MODE_FPGA) {
err = osspec_mutex_lock(hnd->mutex_cfg, X502_MUTEX_CFG_LOCK_TOUT);
if (!err) {
int32_t release_err;
/* маскированные биты берем из последнего выведенного значения */
if (msk) {
val = val & ~msk;
val |= hnd->last_dout & msk;
}
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_ASYNC_OUT,
val | X502_STREAM_OUT_WORD_TYPE_DOUT);
/* сохраняем выведенное значения, для последующего использования
в маске */
if (!err)
hnd->last_dout = val;
release_err = osspec_mutex_release(hnd->mutex_cfg);
if (!err)
err = release_err;
}
} else if (hnd->mode == X502_MODE_DSP) {
uint32_t wrds[2] = {val, msk};
err = X502_BfExecCmd(hnd, L502_BF_CMD_CODE_ASYNC_OUT, L502_BF_CMD_ASYNC_TYPE_DOUT,
wrds, 2, NULL, 0, X502_BF_CMD_DEFAULT_TOUT, NULL);
} else {
err = X502_ERR_INVALID_MODE;
}
}
return err;
}
static int32_t f_read_digin(t_x502_hnd hnd, uint32_t* din) {
int32_t err = 0;
uint32_t val;
int rdy=0;
t_ltimer tmr;
/* читаем состояние входов, чтобы сбросить флаг готовности */
if (!x502_is_E16(hnd)) {
err = hnd->iface_hnd->fpga_reg_read(hnd, X502_REGS_IOARITH_DIN_ASYNC, &val);
}
/* читаем синхронный ввод до готовности данных или пока не
выйдем по таймауту*/
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(500));
while (!rdy && !ltimer_expired(&tmr) && (err == X502_ERR_OK)) {
err = hnd->iface_hnd->fpga_reg_read(hnd, X502_REGS_IOARITH_DIN_ASYNC, &val);
if (!err && (val & 0x80000000)) {
rdy = 1;
*din = (val & 0x3FFFF);
}
}
if (!err && !rdy)
err = X502_ERR_DIG_IN_NOT_RDY;
return err;
}
X502_EXPORT(int32_t) X502_AsyncInDig(t_x502_hnd hnd, uint32_t* din) {
int32_t err = X502_CHECK_HND_OPENED(hnd);
if (!err & (din==NULL))
err = X502_ERR_INVALID_POINTER;
if (!err)
err = osspec_mutex_lock(hnd->mutex_cfg, X502_MUTEX_CFG_LOCK_TOUT);
if (!err) {
if (x502_is_E16(hnd)) {
err = f_read_digin(hnd, din);
} else if (hnd->mode == X502_MODE_FPGA) {
if (hnd->flags & PRIV_FLAGS_STREAM_RUN) {
err = f_read_digin(hnd, din);
} else {
/* запрещаем прием данных */
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOARITH_IN_STREAM_ENABLE, 0);
if (!err) {
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_PRELOAD_ADC, 1);
if (!err) {
/* запускаем чтение цифровых входов */
err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_GO_SYNC_IO, 1);
}
}
if (!err) {
int32_t stop_err;
err = f_read_digin(hnd, din);
/* останавливаем сбор данных */
stop_err = hnd->iface_hnd->fpga_reg_write(hnd, X502_REGS_IOHARD_GO_SYNC_IO, 0);
if (!err)
err = stop_err;
}
}
} else if (hnd->mode == X502_MODE_DSP) {
err = X502_BfExecCmd(hnd, L502_BF_CMD_CODE_ASYNC_DIG_IN,
0, NULL, 0, din, 1, X502_BF_CMD_DEFAULT_TOUT, NULL);
} else {
err = X502_ERR_INVALID_MODE;
}
osspec_mutex_release(hnd->mutex_cfg);
}
return err;
}