144 lines
5.5 KiB
C
144 lines
5.5 KiB
C
#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;
|
||
}
|