#include "l502api.h" #include "l502api_private.h" #include "l502_fpga_regs.h" #include #include #include /* минимальный размер внутреннего буфера */ #define L502_DMA_IN_BUF_SIZE_MIN 16*1024 #ifdef _WIN32 BOOL WINAPI DllMain(HINSTANCE hmod, DWORD reason, LPVOID resvd) { switch (reason) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } #endif static int32_t f_iface_free_devinfo_ptr(t_x502_devrec_inptr *devinfo_ptr); static int32_t f_iface_stream_cfg(t_x502_hnd hnd, uint32_t ch, t_x502_stream_ch_params *params); static int32_t f_iface_cycle_load_start(t_x502_hnd hnd, uint32_t size); static int32_t f_iface_cycle_setup(t_x502_hnd hnd, uint32_t flags); static int32_t f_iface_cycle_stop(t_x502_hnd hnd, uint32_t flags); static int32_t f_iface_cycle_check_setup(t_x502_hnd hnd, uint32_t *done); static int32_t f_iface_check_feature(t_x502_hnd hnd, uint32_t feature); static const t_x502_dev_iface f_pcie_iface = { L502_REGS_HARD_ID, L502_DMA_IN_BUF_SIZE_MIN, 0, L502_BF_REQ_DATA_SIZE_MAX, 4, //flash rd size 1, //flash wr size f_iface_free_devinfo_ptr, l502_port_open, l502_port_close, l502_port_fpga_reg_read, l502_port_fpga_reg_write, f_iface_stream_cfg, l502_port_stream_start, l502_port_stream_stop, l502_port_stream_free, NULL, l502_port_stream_read, l502_port_stream_write, l502_port_stream_rdy_size, l502_iface_bf_mem_block_rd, l502_iface_bf_mem_block_wr, l502_iface_bf_firm_load, l502_iface_flash_rd, l502_iface_flash_wr, l502_iface_flash_erase, l502_iface_flash_set_prot, l502_port_renew_info, f_iface_cycle_load_start, f_iface_cycle_setup, f_iface_cycle_stop, f_iface_cycle_check_setup, NULL, NULL, f_iface_check_feature }; X502_EXPORT(int32_t) L502_GetDriverVersion(t_x502_hnd hnd, uint32_t* ver) { int32_t err = X502_CHECK_HND(hnd); if (err == X502_ERR_OK) err = l502_port_get_drv_ver(hnd, ver); return err; } int32_t l502_devlist_gen(t_x502_devrec *info, void *iface_data) { int32_t err = X502_ERR_OK; t_x502_devrec_inptr *devinfo_ptr = calloc(1, sizeof(t_x502_devrec_inptr)); if (devinfo_ptr == NULL) { err = X502_ERR_MEMORY_ALLOC; } else { devinfo_ptr->iface_data = iface_data; devinfo_ptr->iface = &f_pcie_iface; info->iface = X502_IFACE_PCI; info->flags |= X502_DEVFLAGS_IFACE_SUPPORT_PCI | X502_DEVFLAGS_FPGA_LOADED; info->internal = devinfo_ptr; } return err; } X502_EXPORT(int32_t) L502_GetSerialList(char serials[][X502_SERIAL_SIZE], uint32_t size, uint32_t flags, uint32_t *devcnt) { return X502_GetSerialList(serials, size, flags, devcnt, L502_DEVICE_NAME, L502_GetDevRecordsList); } X502_EXPORT(int32_t) L502_Open(t_x502_hnd hnd, const char *serial) { return X502_Open(hnd, serial, L502_DEVICE_NAME, L502_GetDevRecordsList); } static int32_t f_iface_free_devinfo_ptr(t_x502_devrec_inptr *devinfo_ptr) { l502_port_free_iface_data(devinfo_ptr->iface_data); free(devinfo_ptr); return X502_ERR_OK; } static int32_t f_iface_stream_cfg(t_x502_hnd hnd, uint32_t ch, t_x502_stream_ch_params *params) { t_lpcie_stream_ch_params lpcie_ch_params; memset(&lpcie_ch_params, 0, sizeof(lpcie_ch_params)); lpcie_ch_params.ch = ch; lpcie_ch_params.irq_step = params->step; lpcie_ch_params.buf_size = params->buf_size; return l502_port_stream_set_params(hnd, &lpcie_ch_params); } static int32_t f_iface_cycle_load_start(t_x502_hnd hnd, uint32_t size) { uint32_t irq_step = STREAM_OUT_IRQ_STEP(hnd); return l502_port_cycle_load_start(hnd, L502_DMA_CHNUM_OUT, size, irq_step); } static int32_t f_iface_cycle_setup(t_x502_hnd hnd, uint32_t flags) { return l502_port_cycle_setup(hnd, L502_DMA_CHNUM_OUT, (flags & X502_OUT_CYCLE_FLAGS_FORCE) ? LPCIE_CYCLE_SW_EVT_IMMIDIATLY : LPCIE_CYCLE_SW_EVT_END_OF_CYCLE); } static int32_t f_iface_cycle_stop(t_x502_hnd hnd, uint32_t flags) { return l502_port_cycle_stop(hnd, L502_DMA_CHNUM_OUT, (flags & X502_OUT_CYCLE_FLAGS_FORCE) ? LPCIE_CYCLE_SW_EVT_IMMIDIATLY : LPCIE_CYCLE_SW_EVT_END_OF_CYCLE); } static int32_t f_iface_cycle_check_setup(t_x502_hnd hnd, uint32_t *done) { uint32_t ver; int32_t err = L502_GetDriverVersion(hnd, &ver); if ((err == X502_ERR_OK) && !LPCIE_IOCTL_SUPPORT_CYCLE_CHECK_SETUP(ver)) err = X502_ERR_NOT_SUP_BY_DRIVER; if (err == X502_ERR_OK) err = l502_port_cycle_check_setup(hnd, L502_DMA_CHNUM_OUT, done); if (err == X502_ERR_OK) { /* за счет буфера в плате на вывод может пройти несколько мс после * передачи в модуль данных до того как реально эти данные появятся * на выходе. т.к. это отследить явно нельзя, то приходится ставить задержку */ SLEEP_MS(3); } return err; } static int32_t f_iface_check_feature(t_x502_hnd hnd, uint32_t feature) { int32_t err = X502_ERR_NOT_SUP_BY_FIRMWARE; switch (feature) { case X502_FEATURE_OUT_FREQ_DIV: case X502_FEATURE_OUT_STATUS_FLAGS: if (hnd->info.fpga_ver >= 0x5) err = X502_ERR_OK; break; default: err = X502_ERR_UNKNOWN_FEATURE_CODE; break; } return err; }