#include "stdafx.h" #include "GScanO200.h" #include "UsbScanEx.h" #include "StopWatch.h" #include "scn_config.h" #include "ImageMatQueue.h" #include "ImageProcess/ImageApplyDogEarDetection.h" #include "filetools.h" #include "GetMemoryUsage.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, //获取滚轴数 GET_ROLLER_NUM = 0x1e, //清零滚轴数 CLR_ROLLER_NUM = 0x1f, //清除扫描总张数 CLR_SCAN_NUM = 0x20, //准备更新固件 PRE_UPGRADE = 0X21, //开始更新固件 START_UPGRADE = 0x22, //彩色的AD参数 RGB_ADI_PARA = 0x23, //灰度的AD参数 ADI_PARA = 0x24, //获取CIS参数(曝光时间,ad参数) GET_CIS_PARA = 0x25, //扫描张数 START_COMMAND_COUNT = 0x26, //下发休眠时间 SET_SLEEP_TIME = 0x27, //获取休眠时间 GET_SLEEP_TIME = 0x28, //清除缓存 CLR_CACHE = 0x29, //下发速度模式 SET_SPEED_MODE = 0x2a, //获取扫描速度模式 GET_SPEED_MODE = 0X2b, //设置固件版本一共8个字节 SET_FW_VERSION = 0X2c, //获取DSP版本 GET_DSP_VERSION = 0X2d, //采集板FPGA固件版本 GET_SCANFPGA_VERSION = 0x2e, //电机板FPGA固件版本 GET_MOTORFPGA_VERSION = 0X2f, //设置制造商信息 SET_USB_INFOR_MANUFACTURE = 0X30, //获取制造商信息 GET_USB_INFOR_MANUFACTURE = 0X31, //设置产品型号信息 SET_USB_INFOR_MODEL_NAME = 0X32, //获取产品型号信息 GET_USB_INFOR_MODEL_NAME = 0X33, //设置USB PID / VID信息 SET_USB_INFOR_VIDPID = 0X34, GET_USB_INFOR_VIDPID = 0X35, //设置卡纸急停检测灵敏度 SET_JAM_DETECT_SENSITIVE = 0X36, //获取卡纸急停检测灵敏度 GET_JAM_DETECT_SENSITIVE = 0X37, //设置横向畸变系数 SET_JUST_COF_H = 0x38, //读取横向畸变系数 GET_JUST_COF_H = 0x39, //设置纵向畸变系数 SET_JUST_COF_V = 0x41, //读取纵向畸变系数 GET_JUST_COF_V } UsbKeyWords, * PUsbKeyWords; GScanO200::GScanO200() : huagods(NULL), image_num(0), m_bread_fixed_ratio_fromDSP(false) { m_pImages.reset(new ImageMatQueue()); m_pImages->Getimagenumber = std::bind(&GScanO200::Getimagenumber,this, std::placeholders::_1); } GScanO200::~GScanO200() { if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); m_threadUsb.reset(); } if (m_usb.get()) m_usb.reset(); } void GScanO200::Getimagenumber(bool isadd) { if (isadd) { image_num++; } else { image_num--; } } void GScanO200::DogEar_callback(std::function fun) { m_pImages->DogEarDetection_callback = fun; } 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(); USBCB status = { GET_DSP_STATUS ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&status, sizeof(status)); if (m_usb.get() && m_usb->is_connected()) m_usb->read_bulk(&status, sizeof(status)); if (ret) { m_usb->set_usbhotplug_callback(usbhotplug_callback, this); } } if (this->IsConnected()) GetFWVersion(); } void GScanO200::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata) { huagods = usrdata; dev_callback = callback; } #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(); //writelog("aquire_bmpdata 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()); //static int aqimgindex = 0; //writelog("aquireed image " + to_string(++aqimgindex)); //FileTools::write_log("C:\\Users\\huagao\\Desktop\\out.txt", "aquired procced image "+ to_string(++aqimgindex)); #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.resize(8); USBCB cmd = { GET_FW_VERSION,fwVersion.size(),0, }; m_usb->write_bulk(&cmd, sizeof(cmd)); m_usb->read_bulk(&fwVersion[0], fwVersion.size()); std::string ver = fwVersion.substr((fwVersion.length() - 2), 2); int verValue = atoi(ver.c_str()); m_bread_fixed_ratio_fromDSP = verValue >= 15; //writelog(m_bread_fixed_ratio_fromDSP ? "can get ratio from dsp" : "can not get dsp ratio"); updateHVRatio(); } return fwVersion; } return ""; } std::string GScanO200::GetSerialNum() { //return "G20018000298"; if (m_usb.get() && m_usb->is_connected()) { std::lock_guard lck(m_imgLocker); if (SerialNum.empty()) { SerialNum.resize(12); USBCB usbcb = { GET_SERIAL,SerialNum.size(),0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&SerialNum[0], SerialNum.size()); } 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()) { hgConfigClass cfg = hgConfigClass(params); gcap = params; UINT32 cfgdata = cfg.GetData(); USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 }; FileTools::write_log("USB config_params:"+to_string(cfgdata)+"\npaper:"+to_string(cfgdata&0x1f) + "\ncolor:" + to_string((cfgdata>>5) & 0x1) + "\ndpi:" + to_string((cfgdata>>6) & 0x3) + "\ndouble_feed_enbale:" + to_string((cfgdata>>8) & 0x1) + "\nstable_enbale:" + to_string((cfgdata>>9) & 0x1) + "\nscrew_detect_enable:" + to_string((cfgdata>>10) & 0x1) + "\nscrew_detect_level:" + to_string((cfgdata>>11) & 0x7) + "\nunused_one:" + to_string((cfgdata>>14) & 0x3F) + "\npc_correct:" + to_string((cfgdata>>20) & 0x1) + "\nunused_two:" + to_string((cfgdata>>21) & 0x7ff)); m_usb->write_bulk(&usbcb, sizeof(USBCB)); this_thread::sleep_for(std::chrono::milliseconds(200)); m_pImages->setparam(params); } } void GScanO200::Scanner_StartScan(UINT16 count) { std::lock_guard lck(m_imgLocker); if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); } USBCB status = { GET_DSP_STATUS ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&status, sizeof(status)); if (m_usb.get() && m_usb->is_connected()) m_usb->read_bulk(&status, sizeof(status)); switch (status.u32_Data) { 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: m_pImages->setscanflags(false); devState = DEV_WRONG; Set_ErrorCode(status.u32_Data); if (huagods) dev_callback(status.u32_Data, huagods); return; default: break; } #ifndef G200 USBCB paperstatus = { GET_PAPER_STATUS ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&paperstatus, sizeof(paperstatus)); if (m_usb.get() && m_usb->is_connected()) m_usb->read_bulk(&paperstatus, sizeof(paperstatus)); if (paperstatus.u32_Data == 0) { m_pImages->setscanflags(false); devState = DEV_WRONG; Set_ErrorCode(NO_FEED); if (huagods) dev_callback(NO_FEED, huagods); return; } #endif // !G200 m_pImages->reset_DogEar(); if (gcap.is_duplex) count = count == 65535 ? 65535 : count / 2; USBCB usbcb = { START_COMMAND,(UINT32)count ,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&usbcb, sizeof(usbcb)); this_thread::sleep_for(std::chrono::milliseconds(200)); if (m_usb.get() && m_usb->is_connected()) { m_pImages->setscanflags(true); m_threadUsb.reset(new std::thread(&GScanO200::usbmain, this)); m_pImages->run(); } } void GScanO200::Stop_scan() { std::lock_guard lck(m_imgLocker); USBCB usbcb = { STOP ,0,0 }; if (m_usb.get() && m_usb->is_connected()) 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 }; if (m_usb.get() && m_usb->is_connected()) 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() { std::lock_guard lck(m_imgLocker); USBCB usbcb = { GET_SCANN_NUM ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&usbcb, sizeof(usbcb)); return usbcb.u32_Count; } void GScanO200::clear_hwerror() { ; } 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); if (m_usb.get()) m_usb.reset(); if (huagods) dev_callback(USB_DISCONNECTED, huagods); } } void GScanO200::updateHVRatio() { if (m_usb.get() && !m_usb->is_connected()) return; if (m_bread_fixed_ratio_fromDSP) { USBCB usbcb = { GET_JUST_COF_H ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); float hratio = *((float*)(&usbcb.u32_Data)); usbcb = { GET_JUST_COF_V ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); float vratio = *((float*)(&usbcb.u32_Data)); m_pImages->updatefixratio(hratio, vratio); } } void GScanO200::usbmain() { std::shared_ptr> imgData; devState = DEV_ISRUNNING; bool haveError = false; try { StopWatch sw; while (devState == DEV_ISRUNNING) { if ((m_usb.get() && !m_usb->is_connected())) { this_thread::sleep_for(chrono::milliseconds(200)); break; } if (sw.elapsed_ms() > 10000) { m_pImages->setscanflags(false); devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP; return; } if(gcap.resolution_dst>200.0f) { if (m_pImages->orginimgcount() > 2) { this_thread::sleep_for(chrono::milliseconds(10)); continue; } } USBCB usbcb = Get_Scanner_Status(); switch (usbcb.u32_Data) { case HAVE_IMAGE: { int totalNum = usbcb.u32_Count; m_usb->set_timeout(2000); imgData = Get_Img_Data(totalNum); if (!imgData->size()) { Stop_scan(); writelog("imgData->size() error"); break; } if(!m_pImages->get_isDogEar()) m_pImages->pushMat(std::shared_ptr(new G200Decode(imgData))); m_usb->set_timeout(200); Pop_Image(); sw.reset(); break; } case STOP_SCAN: m_pImages->setscanflags(false); devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP; //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: case SIZE_ERROR: Set_ErrorCode(usbcb.u32_Data); m_pImages->setscanflags(false); devState = DEV_WRONG; if (huagods) dev_callback(usbcb.u32_Data, huagods); break; case NORMAL: break; default: break; } this_thread::sleep_for(chrono::milliseconds(10)); } } catch (const std::exception& e) { writelog(e.what()); } ////FileTools::write_log("D:\\1.txt", "thread usb exit"); } /////////////////////////////////////////////////////////////////////////// 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 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&usbcb, sizeof(usbcb)); if (m_usb.get() && m_usb->is_connected()) m_usb->read_bulk(&usbcb, sizeof(usbcb)); return usbcb; } std::shared_ptr> GScanO200::Get_Img_Data(int bufferSize) { if (m_usb.get() && !m_usb->is_connected()) return std::shared_ptr>(new std::vector()); std::shared_ptr> imData(new std::vector(bufferSize)); StopWatch sw; int readed = 0; USBCB usbcb = { GET_IMAGE,0,bufferSize }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); int totalength = bufferSize; int startindex = 0; while (totalength > 0) { int dstlength = 1024 * 1024; if (totalength <= dstlength) { dstlength = totalength; totalength = 0; } else totalength -= dstlength; int tt = m_usb->read_bulk(imData->data() + startindex, dstlength); startindex += dstlength; } if (sw.elapsed_ms() > 5000) { writelog("Usb read data timeout\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)); }