311 lines
12 KiB
C
311 lines
12 KiB
C
#ifndef X502API_PRIVATE_H
|
|
#define X502API_PRIVATE_H
|
|
|
|
|
|
#ifdef _WIN32
|
|
#include <Windows.h>
|
|
#else
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
#endif
|
|
|
|
#include "x502api.h"
|
|
#include "osspec.h"
|
|
#include "l502_bf_cmd_defs.h"
|
|
#include "x502_fpga_regs.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
struct st_x502_devrec_inptr {
|
|
const void *iface;
|
|
void *iface_data;
|
|
};
|
|
|
|
#define E16_DEVICE_NAME "E16"
|
|
|
|
#define X502_SIGN 0xA55A0502
|
|
|
|
|
|
#define X502_CHECK_HND(hnd) ((hnd!=NULL) ? (hnd)->sign == X502_SIGN ? X502_ERR_OK \
|
|
: X502_ERR_INVALID_HANDLE : X502_ERR_INVALID_HANDLE)
|
|
|
|
#define X502_CHECK_HND_OPENED(hnd) ((hnd!=NULL) ? (hnd)->sign == X502_SIGN ? \
|
|
(((hnd)->flags & PRIV_FLAGS_OPENED) ? X502_ERR_OK : X502_ERR_DEVICE_NOT_OPENED) \
|
|
: X502_ERR_INVALID_HANDLE : X502_ERR_INVALID_HANDLE)
|
|
|
|
|
|
|
|
|
|
/* на сколько секунд данных будет рассчитан внутренний буфер */
|
|
#define X502_DMA_IN_BUF_FOR_SEC 4
|
|
/* максимальное кол-во прерываний в секунду */
|
|
#define X502_DMA_IN_MAX_IRQ_PER_SEC 20
|
|
|
|
#define X502_DMA_OUT_BUF_SIZE (3*3*1024*1024)
|
|
#define X502_DMA_OUT_IRQ_STEP (3*1024*1024/32)
|
|
|
|
|
|
|
|
#define X502_MUTEX_CFG_LOCK_TOUT 1000
|
|
|
|
#define X502_OUT_CYCLE_WAIT_TOUT 20000
|
|
|
|
|
|
#define X502_STREAM_CH_CNT 2
|
|
|
|
|
|
#ifdef _WIN32
|
|
#define SLEEP_MS(ms) Sleep(ms)
|
|
#else
|
|
#define SLEEP_MS(ms) usleep(ms*1000)
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/** параметры канала потока данных */
|
|
typedef struct {
|
|
uint32_t buf_size; /** размер временного буфера */
|
|
uint32_t step; /** через сколько переданных отсчетов будет генерироваться прерывание */
|
|
} t_x502_stream_ch_params;
|
|
|
|
|
|
|
|
typedef int32_t (*t_x502_iface_free_devinfo_ptr)(t_x502_devrec_inptr *devinfo_ptr);
|
|
|
|
typedef int32_t (*t_x502_iface_open)(t_x502_hnd hnd, const t_x502_devrec *devinfo);
|
|
typedef int32_t (*t_x502_iface_close)(t_x502_hnd hnd);
|
|
typedef int32_t (*t_x502_iface_fpga_reg_read)(t_x502_hnd hnd, uint32_t addr, uint32_t *val);
|
|
typedef int32_t (*t_x502_iface_fpga_reg_write)(t_x502_hnd hnd, uint32_t addr, uint32_t val);
|
|
|
|
typedef int32_t (*t_x502_iface_stream_cfg)(t_x502_hnd hnd, uint32_t ch, t_x502_stream_ch_params *pars);
|
|
typedef int32_t (*t_x502_iface_stream_start)(t_x502_hnd hnd, uint32_t ch, uint32_t flags);
|
|
typedef int32_t (*t_x502_iface_stream_stop)(t_x502_hnd hnd, uint32_t ch, uint32_t flags);
|
|
typedef int32_t (*t_x502_iface_stream_free)(t_x502_hnd hnd, uint32_t ch, uint32_t flags);
|
|
typedef int32_t (*t_x502_iface_stream_running)(t_x502_hnd hnd, uint32_t ch, int32_t* running);
|
|
typedef int32_t (*t_x502_iface_stream_read)(t_x502_hnd hnd, uint32_t *buf, uint32_t size, uint32_t tout);
|
|
typedef int32_t (*t_x502_iface_stream_write)(t_x502_hnd hnd, const uint32_t *buf, uint32_t size, uint32_t tout);
|
|
typedef int32_t (*t_x502_iface_stream_get_rdy_cnt)(t_x502_hnd hnd, uint32_t ch, uint32_t *rdy_cnt);
|
|
|
|
typedef int32_t (*t_x502_iface_bf_mem_block_rd)(t_x502_hnd hnd, uint32_t addr, uint32_t *block, uint32_t size);
|
|
typedef int32_t (*t_x502_iface_bf_mem_block_wr)(t_x502_hnd hnd, uint32_t addr, const uint32_t *block, uint32_t size);
|
|
typedef int32_t (*t_x502_iface_bf_firm_load)(t_x502_hnd hnd, const char* filename);
|
|
|
|
typedef int32_t (*t_x502_iface_flash_rd)(t_x502_hnd hnd, uint32_t addr, uint8_t* data, uint32_t size);
|
|
typedef int32_t (*t_x502_iface_flash_wr)(t_x502_hnd hnd, uint32_t addr, const uint8_t* data, uint32_t size);
|
|
typedef int32_t (*t_x502_iface_flash_erase)(t_x502_hnd hnd, uint32_t addr, uint32_t size);
|
|
typedef int32_t (*t_x502_iface_flash_set_prot)(t_x502_hnd hnd, uint32_t flags,
|
|
const uint8_t* prot_data, uint32_t size);
|
|
|
|
|
|
typedef int32_t (*t_x502_iface_reload_devinfo)(t_x502_hnd hnd);
|
|
|
|
typedef int32_t (*t_x502_iface_cycle_load_start)(t_x502_hnd hnd, uint32_t size);
|
|
typedef int32_t (*t_x502_iface_cycle_setup)(t_x502_hnd hnd, uint32_t flags);
|
|
typedef int32_t (*t_x502_iface_cycle_stop)(t_x502_hnd hnd, uint32_t flags);
|
|
typedef int32_t (*t_x502_iface_cycle_check_setup)(t_x502_hnd hnd, uint32_t *done);
|
|
|
|
|
|
typedef int32_t (*t_x502_iface_gen_ioctl)(t_x502_hnd hnd, uint32_t cmd_code, uint32_t param,
|
|
const void* snd_data, uint32_t snd_size,
|
|
void* rcv_data, uint32_t recv_size,
|
|
uint32_t* recvd_size, uint32_t tout);
|
|
|
|
typedef int32_t (*t_x502_iface_check_feature)(t_x502_hnd hnd, uint32_t feature);
|
|
|
|
typedef int32_t (*t_x502_iface_fpga_mode_init)(t_x502_hnd hnd);
|
|
|
|
typedef enum {
|
|
X502_STREAM_FLAG_SINGLE = 0x01,
|
|
X502_STREAM_FLAG_NO_REQUEST = 0x02
|
|
} t_x502_streams_flags;
|
|
|
|
|
|
typedef struct {
|
|
uint16_t id_reg_addr;
|
|
uint16_t in_stream_buf_min;
|
|
uint16_t ioctl_max_data_size;
|
|
uint16_t bf_mem_block_size;
|
|
uint16_t flash_rd_size; /**< Максимальный размер чтения из flash-памяти за один запрос */
|
|
uint16_t flash_wr_size; /**< Максимальный размер записи во flash-память за один запрос */
|
|
t_x502_iface_free_devinfo_ptr free_devinfo_ptr;
|
|
t_x502_iface_open open;
|
|
t_x502_iface_close close;
|
|
t_x502_iface_fpga_reg_read fpga_reg_read;
|
|
t_x502_iface_fpga_reg_write fpga_reg_write;
|
|
t_x502_iface_stream_cfg stream_cfg;
|
|
t_x502_iface_stream_start stream_start;
|
|
t_x502_iface_stream_stop stream_stop;
|
|
t_x502_iface_stream_free stream_free;
|
|
t_x502_iface_stream_running stream_running;
|
|
t_x502_iface_stream_read stream_read;
|
|
t_x502_iface_stream_write stream_write;
|
|
t_x502_iface_stream_get_rdy_cnt stream_get_rdy_cnt;
|
|
t_x502_iface_bf_mem_block_rd bf_mem_block_rd;
|
|
t_x502_iface_bf_mem_block_wr bf_mem_block_wr;
|
|
t_x502_iface_bf_firm_load bf_firm_load;
|
|
t_x502_iface_flash_rd flash_rd;
|
|
t_x502_iface_flash_wr flash_wr;
|
|
t_x502_iface_flash_erase flash_erase;
|
|
t_x502_iface_flash_set_prot flash_set_prot;
|
|
t_x502_iface_reload_devinfo reload_dev_info;
|
|
t_x502_iface_cycle_load_start cycle_load_start;
|
|
t_x502_iface_cycle_setup cycle_setup;
|
|
t_x502_iface_cycle_stop cycle_stop;
|
|
t_x502_iface_cycle_check_setup cycle_check_setup;
|
|
t_x502_iface_fpga_mode_init fpga_mode_init;
|
|
t_x502_iface_gen_ioctl gen_ioctl;
|
|
t_x502_iface_check_feature check_feature;
|
|
} t_x502_dev_iface;
|
|
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
STREAM_IN_WRD_ADC = 0,
|
|
STREAM_IN_WRD_DIN = 1,
|
|
STREAM_IN_WRD_MSG = 2,
|
|
STREAM_IN_WRD_USR = 3,
|
|
STREAM_IN_WRD_TSP = 4,
|
|
} t_stream_in_wrd_type;
|
|
|
|
|
|
|
|
typedef enum {
|
|
PRIV_FLAGS_OPENED = 0x0001,
|
|
PRIV_FLAGS_PRELOAD_DONE = 0x0002,
|
|
PRIV_FLAGS_CYCLE_MODE = 0x0004,
|
|
PRIV_FLAGS_STREAM_RUN = 0x0080
|
|
} t_x502_state_flags;
|
|
|
|
typedef enum {
|
|
X502_RELOAD_FLAGS_NO_DAC = 0x0001,
|
|
X502_RELOAD_FLAGS_NO_ADC = 0x0002
|
|
} t_x502_reload_flags;
|
|
|
|
/** структура, описывающая параметры логического канала */
|
|
typedef struct {
|
|
uint32_t ch; /** физический номер канала */
|
|
uint32_t mode; /** режим работы канала из #t_l502_ch_mode */
|
|
uint32_t range; /** диапазон измерения */
|
|
uint32_t avg; /** коэффициент усреднения */
|
|
} t_x502_lch;
|
|
|
|
typedef struct {
|
|
t_x502_lch lch[X502_LTABLE_MAX_CH_CNT];
|
|
uint32_t lch_cnt;
|
|
uint32_t adc_freq_div;
|
|
uint32_t adc_frame_delay;
|
|
uint32_t din_freq_div;
|
|
uint32_t sync_mode;
|
|
uint32_t sync_start_mode;
|
|
uint32_t ref_freq;
|
|
double ext_ref_freq;
|
|
uint32_t out_freq_div;
|
|
uint32_t adc_sync_ch;
|
|
uint32_t adc_sync_range;
|
|
uint32_t adc_sync_mode;
|
|
double adc_sync_val;
|
|
double dac_range;
|
|
uint32_t dac_code_max;
|
|
uint32_t adc_code_max;
|
|
const double *f_scales;
|
|
} t_x502_settings;
|
|
|
|
|
|
|
|
typedef struct st_x502 {
|
|
uint32_t sign; /* признак описателя L502/E502 */
|
|
t_x502_iface iface;
|
|
const t_x502_dev_iface *iface_hnd;
|
|
void *iface_data;
|
|
t_x502_state_flags flags; /* флаги состояния платы */
|
|
t_x502_streams streams; /* какие синхронные потоки разрешены */
|
|
t_x502_mode mode; /* режим работы (через ПЛИС или DSP) */
|
|
t_x502_info info;
|
|
t_x502_settings set; /* настройки платы */
|
|
|
|
t_x502_stream_ch_params stream_pars[X502_STREAM_CH_CNT];
|
|
|
|
uint32_t last_dout; /* последнее выданное значение на DIGOUT */
|
|
uint32_t proc_adc_ch; /* ожидаемый логический канал для следующей ProcessData() */
|
|
|
|
|
|
t_mutex mutex_cfg; /* мьютекс для доступа к полям параметров и состояния модуля */
|
|
t_mutex mutex_bf; /* мьютекс для доступа к памяти сигнального процессора */
|
|
|
|
uint32_t bf_ver; /* версия прошивки BlackFin, если есть */
|
|
uint32_t bf_features; /* дополниельные возможности, поддерживаемые прошивкой */
|
|
} t_x502;
|
|
|
|
|
|
typedef int32_t (APIENTRY *t_x502_get_devinfo_list_cb)(t_x502_devrec* list, uint32_t size,
|
|
uint32_t flags, uint32_t* devcnt);
|
|
|
|
|
|
|
|
bool x502_is_E16(t_x502_hnd hnd);
|
|
|
|
int x502_check_eeprom(t_x502_hnd hnd, uint32_t flags);
|
|
|
|
X502_EXPORT(int32_t) X502_DevRecordInit(t_x502_devrec *info);
|
|
X502_EXPORT(int32_t) X502_Open(t_x502_hnd hnd, const char* serial,
|
|
const char *devname, t_x502_get_devinfo_list_cb get_list);
|
|
X502_EXPORT(int32_t) X502_GetSerialList(char serials[][X502_SERIAL_SIZE], uint32_t size,
|
|
uint32_t flags, uint32_t *devcnt, const char *devname,
|
|
t_x502_get_devinfo_list_cb get_list);
|
|
|
|
X502_EXPORT(int32_t) X502_FpgaRegWrite(t_x502_hnd hnd, uint32_t reg, uint32_t val);
|
|
X502_EXPORT(int32_t) X502_FpgaRegRead(t_x502_hnd hnd, uint32_t reg, uint32_t *val);
|
|
X502_EXPORT(int32_t) X502_ReloadDevInfo(t_x502_hnd hnd, uint32_t flags);
|
|
|
|
int32_t bf_fpga_reg_rd(t_x502_hnd hnd, uint32_t addr, uint32_t* val);
|
|
int32_t bf_fpga_reg_wr(t_x502_hnd hnd, uint32_t addr, uint32_t val);
|
|
|
|
#define x502_bf_set_par(hnd, par, data, size) X502_BfExecCmd(hnd, L502_BF_CMD_CODE_SET_PARAM, \
|
|
par, data, size, NULL, 0, X502_BF_CMD_DEFAULT_TOUT, NULL)
|
|
|
|
#define x502_bf_get_par(hnd, par, data, size) X502_BfExecCmd(hnd, L502_BF_CMD_CODE_GET_PARAM, \
|
|
par, NULL, 0, data, size, X502_BF_CMD_DEFAULT_TOUT, NULL)
|
|
|
|
|
|
|
|
|
|
#define FILL_HARD_ID_FLAGS(devflags, hard_id) do { \
|
|
if (hard_id & 0x01) { \
|
|
devflags |= X502_DEVFLAGS_DAC_PRESENT; \
|
|
} else { \
|
|
devflags &= ~X502_DEVFLAGS_DAC_PRESENT; \
|
|
} \
|
|
if (hard_id & 0x02) { \
|
|
devflags |= X502_DEVFLAGS_GAL_PRESENT; \
|
|
} else { \
|
|
devflags &= ~X502_DEVFLAGS_GAL_PRESENT; \
|
|
} \
|
|
if (hard_id & 0x04) {\
|
|
devflags |= X502_DEVFLAGS_BF_PRESENT; \
|
|
} else { \
|
|
devflags &= ~X502_DEVFLAGS_BF_PRESENT; \
|
|
} \
|
|
} while(0)
|
|
|
|
|
|
#define STREAM_OUT_IRQ_STEP(hnd) (hnd->stream_pars[X502_STREAM_CH_OUT].step ? \
|
|
hnd->stream_pars[X502_STREAM_CH_OUT].step : \
|
|
X502_DMA_OUT_IRQ_STEP/hnd->set.out_freq_div)
|
|
|
|
#define STREAM_OUT_CFG(hnd, err) do { \
|
|
t_x502_stream_ch_params params; \
|
|
memset(¶ms, 0, sizeof(params)); \
|
|
params.buf_size = hnd->stream_pars[X502_STREAM_CH_OUT].buf_size ? \
|
|
hnd->stream_pars[X502_STREAM_CH_OUT].buf_size : \
|
|
X502_DMA_OUT_BUF_SIZE; \
|
|
params.step = STREAM_OUT_IRQ_STEP(hnd); \
|
|
err = hnd->iface_hnd->stream_cfg(hnd, X502_STREAM_CH_OUT, ¶ms); \
|
|
} while(0)
|
|
|
|
|
|
#endif // X502API_PRIVATE_H
|