#include "GScanO3399.h" #include #include "StopWatch.h" #include #include "usb/CyUsbEx.h" #include "UsbLists.h" #include "ImageMatQueue.h" #define USB_REQ_GET_FPGA_REGS 0x40 #define USB_REQ_SET_FPGA_REGS 0x41 #define USB_REQ_GET_MOTOR_REGS 0x42 #define USB_REQ_SET_MOTOR_REGS 0x43 #define USB_REQ_GET_DEV_STATUS 0x60 #define USB_REQ_GET_DEV_CONFIGURATION 0x61 #define USB_REQ_SET_DEV_CONFIGURATION 0x62 #define USB_REQ_GET_DEV_REGS 0x63 #define USB_REQ_SET_DEV_REGS 0x64 enum Scanner_Reg_Defs { SR_CMD, SR_STATUS, SR_SCAN_COUNT, SR_OS, SR_SENSORS, SR_MOTOR, SR_IM_TYPE, SR_IM_COUNT, SR_IM_TX, SR_IM_FRONT_SIZE, SR_IM_CLEAR, SR_IM_TXING, SR_IM_POP, SR_IM_ABORT, SR_COUNT }; enum Scanner_Cmd_Defs { SC_START, SC_STOP, SC_CLEAR, SC_COUNT }; static std::mutex mx_ctrl; static int scanner_read_reg(std::shared_ptr& usb, int addr) { int val = 0; std::lock_guard lck(mx_ctrl); usb->control_msg(0xc0, USB_REQ_GET_DEV_REGS, addr, 0, 4, &val); return val; } static void scanner_write_reg(std::shared_ptr& usb, int addr, int val) { std::lock_guard lck(mx_ctrl); usb->control_msg(0x40, USB_REQ_SET_DEV_REGS, addr, 0, 4, &val); } static void scanner_cmd(std::shared_ptr& usb, int cmd) { scanner_write_reg(usb, 0, cmd); } Scanner::Scanner() :thpool(1) ,thpoolRx(1) { auto usbls = CyUsbList::find_all(); if (!usbls.empty()) { this->usb = *usbls.begin(); this->usb->open(); b_fu_int = true; } } Scanner::~Scanner() { b_fu_int = false; if (fu_rx.valid()) fu_rx.wait(); b_fu_rx = false; if (fu_rx.valid()) fu_rx.wait(); } void Scanner::start() { scanner_cmd(usb, SC_START); fu_int = thpool.enqueue(&Scanner::int_run, this); } void Scanner::stop() { scanner_cmd(usb , SC_STOP); } bool Scanner::is_runing() { return scanner_read_reg(usb, SR_STATUS); } int Scanner::mode() { return scanner_read_reg(usb, SR_STATUS) & 0x02; } bool Scanner::rx_cmd() { scanner_write_reg(usb, 8, 1); return true; } int Scanner::count() { return scanner_read_reg(usb, SR_SCAN_COUNT); } void Scanner::setdecodepixtype(int twpixtype) { } UINT32 Scanner::get_ErrorCode() { return UINT32(); } void Scanner::Set_ErrorCode(UINT32 value) { } int Scanner::get_scanned_num() { return 0; } int Scanner::get_roller_num() { return 0; } void Scanner::clr_roller_num() { } int Scanner::get_sleep_time() { return 0; } void Scanner::set_sleep_time(int time) { } bool Scanner::clr_hardware_cache() { return false; } void Scanner::int_run() { unsigned char buff[64]; bool brun = false; while (b_fu_int) { if((usb->read_int(buff, sizeof(buff)) == sizeof(buff)) || im_dev_count()) { if (is_runing()) { if (!brun) brun = true; im_rx(); } /*else { devState = DEV_STOP; m_pImages->setscanflags(false); break; }*/ } if (!is_runing() && brun) { brun = false; devState = DEV_STOP; m_pImages->setscanflags(false); break; } } } int Scanner::read_data(void* data, int length, int timeout) { int readed = 0; int reading = 0; const int buffer_size = 2*1024*1024; StopWatch sw; while (readed < length && sw.elapsed_ms() < timeout) { reading = std::max(0, std::min(length - readed, buffer_size)); reading = usb->read_bulk((unsigned char*)data + readed, reading); if (reading > 0) { readed += reading; } } return readed; } int Scanner::front_datasize() { return scanner_read_reg(usb, SR_IM_FRONT_SIZE); } bool Scanner::is_dev_tx() { return scanner_read_reg(usb, SR_IM_TXING); } void Scanner::abort_dev_tx() { scanner_write_reg(usb, SR_IM_ABORT, 1); //!< to-list } void Scanner::open(int vid, int pid) { } int Scanner::open(int vid) { return usb.get() ? 1:0; } bool Scanner::close() { return false; } bool Scanner::is_open() { return false; } void Scanner::setusbreport_callback(usbreport_callback callback, void* usrdata) { } int Scanner::get_image_front_info(ImageInfo* info) { return 0; } int Scanner::aquire_image(cv::Mat& mat, int& bppinfo) { StopWatch sw; while (true) { if (m_pImages->empty()) { if (sw.elapsed_s() > 20.00) { Stop_scan();//ֹͣɨÃè ResetScanner(); return HARDWARE_ERROR; } if (!is_scan()) { if (devState == DEV_WRONG) { return get_ErrorCode(); } return -1; } } else { if (m_pImages->valid()) { auto ret = m_pImages->popimage(); mat = ret.mat.clone(); bppinfo = ret.Bpp; return 0; } #ifdef WIN32 DoEvents();//·ÀÖ¹UI×èÈû #endif // WIN32 this_thread::sleep_for(chrono::milliseconds(1)); } } } void Scanner::clear_hwerror() { } bool Scanner::IsConnected() { return usb->is_connected(); } std::string Scanner::GetFWVersion(int mode) { return std::string(); } std::string Scanner::GetSerialNum(int mode) { return std::string(); } bool Scanner::is_scan() { return is_runing(); } bool Scanner::Get_Scanner_PaperOn() { return true; } void Scanner::config_params(GScanCap& params, int mode) { } void Scanner::Scanner_StartScan(UINT32 count, int mode) { devState = DEV_RUNNING; start(); m_pImages->run(); m_pImages->setscanflags(true); } void Scanner::Stop_scan() { stop(); } void Scanner::ResetScanner() { } void Scanner::reset() { } bool Scanner::Get_IsImageQueueEmpty() { return false; } bool Scanner::is_rx() { return fu_rx.valid() && (fu_rx.wait_for(std::chrono::seconds(0)) != std::future_status::ready); } void Scanner::im_rx() { if (!is_rx() && !is_dev_tx()) { fu_rx = thpoolRx.enqueue([this] { do { /* code */ std::shared_ptr> buffi(new std::vector); int count = front_datasize(); buffi->resize(count); rx_cmd(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); count = read_data(buffi->data(), count, count / (0.01 * 1024 * 1024)); m_pImages->pushMat(std::shared_ptr(new GRawDecode(buffi))); pop_dev_im(); } while (im_dev_count()); }); } } void Scanner::pop_dev_im() { scanner_write_reg(usb, SR_IM_POP, 1); //!< to-list } int Scanner::im_dev_count() { return scanner_read_reg(usb, SR_IM_COUNT); //!< to-list }