#include "stdafx.h" #include "GScanO200.h" #include "UsbScanEx.h" #include "UsbScanEx.h" #include "StopWatch.h" #include "scn_config.h" #include "JpegBuffer.h" #include "ImageMatQueue.h" #include "filetools.h" //u32_CMD typedef enum tagUsbKeyWords : UINT32 { //无命令 NO_COMMAND = 0, //获取dsp 状态 GET_DSP_STATUS = 1, //取图 GET_IMAGE = 2, //销毁DSP中驻存的图 POP_IMAGE = 3, //开始扫描命令 START_COMMAND = 4, //停止扫描命令 STOP = 5, //获取扫描仪扫描模式 GET_SCAN_MODE = 6, //获取固件版本号 GET_FW_VERSION = 7, //返回PC端的状态 SEND_STATUS_PC = 8, //下发扫描配置参数 CONFIGURED_DATA = 9, //下发固件信息 SEND_FW = 10, //获取扫描参数 GET_CONFIG_DATA = 11, //获取扫描总张数 GET_SCANN_NUM = 12, //获取有无纸的状态 GET_PAPERFEEDER_STATUS = 13, //DSP初始化 INIT_HARDWARE_SYS = 14, //获取有无纸的状态 GET_PAPER_STATUS = 0x0d, //下发元器件配置参数(灰度,LED R曝光时间) SEND_COMPONENTS_GR = 15, //下发元器件配置参数(LED G/B曝光时间) SEND_COMPONENTS_GB = 16, //下发扫描模式 SEND_SCAN_MODE = 17, //开始进行平场矫正 START_FLAT = 18, //停止平场矫正 STOP_FLAT = 19, //下发200dpi彩色平场矫正参数 SEND_200_COLOR_FLAT_DATA = 20, //下发300dpi彩色平场矫正参数 SEND_300_COLOR_FLAT_DATA = 21, //获取200dpi彩色平场矫正参数 GET_200_COLOR_FLAT_DATA = 22, //获取300dpi彩色平场矫正参数 GET_300_COLOR_FLAT_DATA = 23, //下发200dpi灰度平场校正参数 SEND_200_GRAY_FLAT_DATA = 24, //下发300dpi灰度平场校正参数 SEND_300_GRAY_FLAT_DATA = 25, //获取200DPI灰度平场校正参数 GET_200_GRAY_FLAT_DATA = 26, //获取300DPI灰度平场校正参数 GET_300_GRAY_FLAT_DATA = 27, //下发序列号命令 SEND_SERIAL = 28, //获取序列号命令 GET_SERIAL = 29 } UsbKeyWords, * PUsbKeyWords; GScanO200::GScanO200() { } GScanO200::~GScanO200() { if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); m_threadUsb.reset(); } } void GScanO200::open(int vid, int pid) { auto usbs = UsbScan_List::find_vid_pid(vid, pid); if (!usbs.empty()) { m_usb = *usbs.begin(); bool ret= m_usb->open(); if (ret) { m_usb->set_usbhotplug_callback(usbhotplug_callback, this); } } } #ifdef LOG_NORMAL fstream fsaquire; static int aquiretimes = 1; #endif // LOG int GScanO200::aquire_bmpdata(std::vector& bmpdata) { StopWatch sw; while (true) { if (m_pImages->empty()) { DoEvents(); this_thread::sleep_for(chrono::milliseconds(1)); if (sw.elapsed_s() > 20.00) { if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); m_threadUsb.reset(); } Stop_scan();//停止扫描 ResetScanner(); return HARDWARE_ERROR; } if (!is_scan()) { if (devState == DEV_WRONG) { return get_ErrorCode(); } return -1; } } else { if (m_pImages->valid()) { bmpdata = m_pImages->popBmpdata(); #ifdef LOG_NORMAL static int aquireindex = 0; FileTools::write_log("out.txt", "aquire image index " + std::to_string(++aquireindex)); #endif // LOG return 0; } DoEvents(); this_thread::sleep_for(chrono::milliseconds(2)); } } } BOOL GScanO200::IsConnected() { return m_usb.get() && m_usb->is_connected(); } std::string GScanO200::GetFWVersion() { if (m_usb.get() && m_usb->is_connected()) { lock_guard< mutex> lock(m_imgLocker); if (fwVersion.empty()) { fwVersion = " "; USBCB cmd= { GET_FW_VERSION,8,0,}; m_usb->write_bulk(&cmd, sizeof(cmd)); m_usb->read_bulk(&fwVersion[0], 8); } return fwVersion; } return ""; } std::string GScanO200::GetSerialNum() { if (m_usb.get() && m_usb->is_connected()) { std::lock_guard lck(m_imgLocker); if (SerialNum.empty()) { SerialNum = " "; USBCB usbcb = { GET_SERIAL,12,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&SerialNum[0], 12); } return SerialNum; } return ""; } bool GScanO200::is_scan() { //std::lock_guard lck(m_imgLocker); return devState == DEV_ISRUNNING; } BOOL GScanO200::Get_Scanner_PaperOn() { if (m_usb.get()&&!m_usb->is_open()) return false; USBCB usbcb = { GET_PAPER_STATUS ,0,0 }; std::lock_guard lck(m_imgLocker); m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); return usbcb.u32_Data != 0; } void GScanO200::config_params(GScanCap& params) { if (m_usb.get()&&m_usb->is_connected()) { IConfig cfg; cfg = hgConfigClass(params); UINT32 cfgdata = cfg.GetData(); USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 }; m_usb->write_bulk(&usbcb, sizeof(USBCB)); m_pImages->setparam(params); } } void GScanO200::Scanner_StartScan(UINT16 count) { if (m_usb.get() && m_usb->is_connected()) { std::lock_guard lck(m_imgLocker); USBCB usbcb = { START_COMMAND,(UINT32)count ,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); if (m_threadUsb && m_threadUsb->joinable()) { m_threadUsb->join(); } m_threadUsb.reset(new std::thread(&GScanO200::usbmain, this)); m_pImages->run(); m_pImages->setscanflags(true); } } void GScanO200::Stop_scan() { if (m_usb.get() && !m_usb->is_connected()) { return; } std::lock_guard lck(m_imgLocker); USBCB usbcb = { STOP ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); } void GScanO200::ResetScanner() { if (m_usb.get() && !m_usb->is_connected()) return; std::lock_guard lck(m_imgLocker); USBCB usbcb = { INIT_HARDWARE_SYS ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); } bool GScanO200::Get_IsImageQueueEmpty() { return m_pImages->empty(); } void GScanO200::reset() { while (!m_pImages->empty()) m_pImages->clear(); } void GScanO200::setdecodepixtype(int twpixtype) { } UINT32 GScanO200::get_ErrorCode() { return Error_Code; } void GScanO200::Set_ErrorCode(UINT32 value) { Error_Code = value; } int GScanO200::get_scanned_num() { if (m_usb.get() && !m_usb->is_connected()) return -1; std::lock_guard lck(m_imgLocker); USBCB usbcb = { GET_SCANN_NUM ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); return usbcb.u32_Count; } void GScanO200::usbhotplug_callback(bool isconnect, void* userdata) { GScanO200* This = (GScanO200*)userdata; This->usbhotplug(isconnect); } void GScanO200::usbhotplug(bool isleft) { if (isleft) { //devState = DEV_WRONG; //Error_Code = USB_DISCONNECTED; //m_pImages->setscanflags(false); } } void GScanO200::usbmain() { std::shared_ptr> imgData; devState = DEV_ISRUNNING; while (devState == DEV_ISRUNNING) { if (m_usb.get() && !m_usb->is_connected()) { this_thread::sleep_for(chrono::milliseconds(200)); continue; } USBCB usbcb = Get_Scanner_Status(); switch (usbcb.u32_Data) { case HAVE_IMAGE: { int totalNum = usbcb.u32_Count; m_usb->set_timeout(1500); imgData = Get_Img_Data(totalNum); if (!imgData->size()) { Stop_scan(); } m_pImages->pushMat(std::shared_ptr(new G200Decode(imgData))); #ifdef LOG_NORMAL static int rawdataindex = 0; FileTools::write_log("out.txt", "Enquque rawbuffer index " + std::to_string(++rawdataindex)); #endif // LOG m_usb->set_timeout(200); Pop_Image(); break; } case STOP_SCAN: m_pImages->setscanflags(false); devState = DEV_STOP; break; case COUNT_MODE: case NO_FEED: case OPEN_COVER: case FEED_IN_ERROR: case PAPER_JAM: case DETECT_DOUBLE_FEED: case DETECT_STAPLE: case PAPER_SKEW: case HARDWARE_ERROR: case PC_SCAN_BUSY_or_ERROR: Set_ErrorCode(usbcb.u32_Data); m_pImages->setscanflags(false); devState = DEV_WRONG; break; case NORMAL: break; default: break; } this_thread::sleep_for(chrono::milliseconds(20)); } } /////////////////////////////////////////////////////////////////////////// USBCB GScanO200::Get_Scanner_Status() { if (m_usb.get() && !m_usb->is_connected()) { return { NO_COMMAND ,PC_SCAN_BUSY_or_ERROR ,0 }; } USBCB usbcb = { GET_DSP_STATUS ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); return usbcb; } std::shared_ptr> GScanO200::Get_Img_Data(int bufferSize) { std::shared_ptr> imData(new std::vector(bufferSize)); StopWatch sw; int readed = 0; while (readed < bufferSize && sw.elapsed_ms() < 5000){ USBCB usbcb = { GET_IMAGE,0,(UINT32)bufferSize }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); readed = m_usb->read_bulk(imData->data(), bufferSize); } if (sw.elapsed_ms() > 3000) { writelog("Usb read data error\n"); } return imData; } /////////////////////////////////////////////////////////////////////////// void GScanO200::Pop_Image() { if (m_usb.get() && !m_usb->is_open()) return; USBCB usbcb = { POP_IMAGE ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); }