#include "Scanner.h" #include #include "filetools.h" #include "fpgacontrol.h" #include "MemoryInfo.h" #include "SysInforTool.h" #include "USBProtocol.h" #define BTNSTART 0 #define BTNSTOP 1 #define BTNPOWER 2 Scanner::Scanner(ScannerGlue glue) : motorZouzhi(), motorCuozhi(), m_glue(glue), m_isPulling(false), m_isDoublePaper(false), isPaperInit(false), m_jamPaper(false), m_jamIn(false), m_correctting(false), waitpapertime(200), m_scansysinfo(nullptr) { cisvendor = GetCisType(); LOG("Scanner init --------- \n"); m_scaninfo = GetScanInfoFromJson(); m_fpga = std::make_shared(); int version = m_fpga->read(15); LOG("FPGA Version = %d \n",m_fpga->read(15)); capturer.reset(new MultiFrameCapture(m_glue, m_fpga,cisvendor)); // capturer.reset(new Capturer(m_glue,m_fpga)); capturer->SetParent(this); fpgacontrol fc(version); if (fc.ifneedupdatefpga()) { if (fc.updatefpga()) { //system("sh /etc/reloadfpga.sh"); system("poweroff"); } else { LOG("error error update fpga error"); } } auto btnevent = [this](const int eventtype) { if (!IsScanning()) //未扫描 { LOG("enter low power mode 000000000000 \n"); if (eventtype == BTNPOWER) { LOG("enter low power mode \n"); system("echo mem > /sys/power/state"); } else if (eventtype == BTNSTART) { // put(S_EVT_START_SCAN); } } else //扫描中 { if (eventtype == BTNSTOP) { put(S_EVT_STOP_SCAN); LOG("BTN_STOP put(S_EVT_STOP_SCAN)"); } } }; sensor = std::make_shared(sysEvent); m_keyboard.reset(new huagao::Keyboard(btnevent)); m_keyboard->init(); motorZouzhi.enablePower(true); motorZouzhi.setSpeed(4000); motorCuozhi.setSpeed(3000); motorCuozhi.setDirection(false); //sensor->isPaperAtScan(); //system("cat /sys/class/gpio/gpio226/value"); sensor->enableDoubleSensor(true); std::this_thread::sleep_for(std::chrono::milliseconds(50)); sensor->enableDoubleSensor(false); FsmState::setScanner(this); threadRunMessageLoop = std::thread(&Scanner::runMessageLoop, this); Motor::enablePower(true); //meminfo = MemoryInfo::GetInstance(); //GetSysInfo(); } Scanner::~Scanner() { Motor::enablePower(false); sysEvent.Clear(); sysEvent.ShutDown(); bMsgLoop = false; threadRunMessageLoop.join(); m_DstScannum = 0; if (threadRunScan.joinable()) threadRunScan.join(); } void Scanner::updateSpeedMode(int speed) { m_scaninfo = GetScanInfoFromJson(); if(m_scaninfo.SpeedMode==0) m_scaninfo.SpeedMode=3; LOG("Scanner SET updateSpeedMode %d------ \n",m_scaninfo.SpeedMode); unsigned int t_dpi=m_config.params.dpi; // if(typeid(*capturer)==typeid(MonoCapturer)) // { // if(m_config.params.dpi==0x03&& m_scansysinfo->IsSmallRam()) // t_dpi=0x02; // else // t_dpi = m_config.params.dpi; // } //if(typeid(*capturer)==typeid(MultiFrameCapture)) //if(m_config.params.pageSize == 17 || m_config.params.pageSize == 19) //长文稿采用600dpi模式扫描 t_dpi = 2; motorCuozhi.speedChange(m_scaninfo.SpeedMode, t_dpi,m_config.params.isColor); motorZouzhi.speedChange(m_scaninfo.SpeedMode, t_dpi,m_config.params.isColor); } void Scanner::startScan() { if (threadRunScan.joinable()) threadRunScan.join(); stop_countdown(); updateSpeedMode(4); // //开始进行扫描 threadRunScan = std::thread(&Scanner::runScan, this); writesyslog(LOG_INFO, getmeminfo()); } void Scanner::runMessageLoop() { std::this_thread::sleep_for(std::chrono::milliseconds(3000));//避免scanpin io 开始异常 GetSysInfo();//待fpga 重启完成 FsmState *fsmState = FsmStateManagerEx::GetState(); while (bMsgLoop) { ScanEvent evt = sysEvent.Take(); //LOG("\n---------------------%d--------------------------\n", evt); fsmState = fsmState->on_event(evt); //printf("current fsmState =%s ",typeid(*fsmState).name()); processevent(fsmState, evt); } } void Scanner::processevent(FsmState *fsmState, ScanEvent event) { LOG("processevent Event:%d\n", (int)event); if (fsmState == nullptr) { LOG("processevent BBBBBBBBBBBBBB Event:%d\n", (int)event); return; } if (typeid(*fsmState) == typeid(CoverOpenState)) { m_glue.m_deviceevent(1, "Cover Open"); } else if (event == S_EVT_SCAN_STOPPED) { if (!m_correctting) { m_glue.m_deviceevent(70, "Scan done"); } } else if (event == S_EVT_JAM_IN) { m_glue.m_deviceevent(4, "Feed error"); } else if (event == S_EVT_DOUBLEPAPER) { m_glue.m_deviceevent(16, "Double feed"); } else if (event == S_EVT_JAM_OUT || typeid(*fsmState) == typeid(ErrorJamState)) { m_glue.m_deviceevent(8, "Jam out"); } else if (typeid(*fsmState) == typeid(ErrorState) && m_jamIn == true) { m_glue.m_deviceevent(4, "Feed error"); } if (!IsScanning() && (typeid(*fsmState) == typeid(ErrorJamState) || typeid(*fsmState) == typeid(CoverOpenState) || (typeid(*fsmState) == typeid(ErrorState) && m_jamIn == true))) { if (!m_correctting) { m_glue.m_deviceevent(70, "Scan Stop"); } } } static int imageindex = 0; void Scanner::runScan() { LOG("-------------Scanner RunScan Start-------------\r\n"); capturer->open(); motorZouzhi.start(); motorCuozhi.pauseWaitForThread(); //capturer->open(); sensor->enableDoubleSensor(false); if (!isPaperInit) { preFeed(); isPaperInit = true; } for (size_t i = 0; i < 16; i++) { std::cout << string_format("reg[%d] = 0x%08x", i, capturer->read(i)) << std::endl; } imageindex = 0; capturer->setFPGATriggerMode(false, 0); capturer->setFanMode(3); sensor->resetPaperPin(); capturer->clearimages(); capturer->resetimageremain(); capturer->setScanFlag(true); bool b_autosize = m_config.params.pageSize==(int)PaperSize::G400_AUTO || m_config.params.pageSize==(int)PaperSize::G400_MAXAUTO || m_config.params.pageSize==(int)PaperSize::G400_MAXSIZE; StopWatch sw; while (m_DstScannum > 0) { m_isDoublePaper = false; m_jamPaper = false; m_jamIn = false; if (!sensor->isPaperStandby()) //无纸 { if (!sensor->waitPaperStandBy(0)) { // this_thread::sleep_for(std::chrono::milliseconds(200)); put(S_EVT_STOP_SCAN); LOG("STOP STOP STOP RUNSCAN \n"); } break; } else { //LOG(" Detect Feeder loaded ,Paper Ready !!! \n"); } sensor->enableDoubleSensor(m_config.params.doubleFeeded); //LOG("enableDoubleSensor QQQQQQQ:%s %s\n", m_config.params.doubleFeeded ? "true" : "false",GetCurrentTimeStamp(2).c_str()); if (m_DstScannum == 0) //被取消扫描了 { LOG("canceled canceled canceled 999999999999999999999999999999999999999999 \n"); break; } motorCuozhi.startAsyn(); if (!sensor->isPaperStandby()) { put(S_EVT_STOP_SCAN); LOG("START SCAN LOOP STOP STOP STOP\n"); isRested = false; break; } isRested = false; if (!sensor->waitPaperIn(3000)) { LOG("START SCAN LOOP S_EVT_JAM_IN S_EVT_JAM_IN S_EVT_JAM_IN\n"); if (!m_isDoublePaper) { m_glue.m_deviceevent(4, "Feed error"); m_jamIn = true; put(S_EVT_JAM_IN); m_scaninfo.JamInNum++; //writesyslog(LOG_INFO, "paper jam in error \n"); } break; } capturer->snap(); motorCuozhi.pauseWaitForThread(); int i = 0; int max = 7; #ifdef G400 if(m_config.params.pageSize >= (int)PaperSize::G400_LONGLETTER) max = m_scaninfo.SpeedMode>3?10:16; else max = m_scaninfo.SpeedMode>3?5:8; #else if(m_config.params.pageSize >= (int)PaperSize::G400_LONGLETTER) max = m_scaninfo.SpeedMode>3?10:25; else max = m_scaninfo.SpeedMode>3?5:8; #endif max = m_config.params.dpi > 2 ? 30 : max * m_config.params.dpi; if(m_config.params.pageSize == 17 || m_config.params.pageSize == 19) max = 200; LOG("paper pauseWaitForThread \n"); waitpapertime = 400; while (!sensor->waitPaperOut(waitpapertime) && i < max) { i++; if (!sensor->isPaperIn()) { LOG("paper 假卡纸了。。。。。\n"); break; } } LOG("paper isPaperIn \n"); if (i == max && sensor->isPaperIn()) { if (!m_isDoublePaper) { m_glue.m_deviceevent(8, "Jam out"); //卡纸 m_jamPaper = true; put(S_EVT_JAM_OUT); m_scaninfo.JamOutNum++; LOG("paper 卡纸了。。。。。\n"); } else { // m_glue.m_deviceevent(16); //双张 // LOG("paper 双张了。。。。。\n"); m_scaninfo.DoubleNum++; } capturer->stopsnap(b_autosize); capturer->waitsnapdone(1);//等待采集完成 this_thread::sleep_for(std::chrono::milliseconds(500));//200 80ms 600 260ms LOG("\n ----------------EXIT 11111---------------- \n"); break; } LOG("\nclose double sensor %s\n",GetCurrentTimeStamp(2).c_str()); sensor->enableDoubleSensor(false); if(b_autosize) { int dly_speed= (5 - m_scaninfo.SpeedMode)*10; int delay = m_config.params.dpi==0x02?70:(m_config.params.dpi==0x03?350: 20); if((m_config.params.pageSize == 17 || m_config.params.pageSize == 19)&&(delay < 350)) delay = 350; if(m_config.params.pageSize == 18) delay = std::max(delay,80); delay+=dly_speed; //LOG("AutoSize sleep_for delay=%d \n",delay); this_thread::sleep_for(std::chrono::milliseconds(delay));//200 80ms 600 260ms } if(b_autosize) { std::this_thread::sleep_for(std::chrono::milliseconds((5 - m_scaninfo.SpeedMode)*10*m_config.params.dpi)); if(sensor->isPaperAtScan()) { m_glue.m_deviceevent((int)HG_ScannerStatus::PAPER_HOLE,"paper have hole"); capturer->waitsnapdone(1);//等待采集完成 capturer->stopsnap(b_autosize); break; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } std::this_thread::sleep_for(std::chrono::milliseconds(500)); LOG("\nclose b_autosize %s\n",GetCurrentTimeStamp(2).c_str()); capturer->stopsnap(b_autosize); capturer->waitsnapdone(m_isDoublePaper || m_jamPaper);//等待采集完成 m_DstScannum--; m_scaninfo.RollerNum++; m_scaninfo.TotalScanned++; if (m_DstScannum == 0) { LOG("\n ----------------EXIT 2222 cnt=%d---------------- \n",m_DstScannum); this_thread::sleep_for(std::chrono::milliseconds(200)); put(S_EVT_STOP_SCAN); break; } sw.reset(); while (meminfo->GetMemoryUsed() > 70.0f||(m_config.params.dpi ==0x03 && capturer->getimageremain()>1)) //内存占用高于75% { if (sw.elapsed_s() < 20.0) std::this_thread::yield(); else { LOG("\n ----------------EXIT 3333---------------- \n"); put(S_EVT_STOP_SCAN); break; } } printf("正常结束\r\n"); } m_DstScannum = 0; sensor->enableDoubleSensor(false); sensor->resetPaperPin(); capturer->setScanFlag(false); int t_delay = m_config.params.dpi == 0x02 ? 150 : (m_config.params.dpi == 0x03 ? 350 : 100); this_thread::sleep_for(std::chrono::milliseconds(t_delay)); //走纸多转一会儿 确保扫描传感器过了之后 纸能出完 capturer->setFanMode(0); capturer->close(); LOG("\n--------------------------scan done --------------------------------\n"); } void Scanner::CreatCorrectData(int correctmode) { m_correctting = true; LOG("\n-----------------校正模式 %d-----------------------\n",correctmode); capturer->createCorrect(correctmode); } void Scanner::preFeed() { int sleeptime = 300; motorCuozhi.feeding(); std::this_thread::sleep_for(std::chrono::milliseconds(sleeptime)); motorCuozhi.pause(); std::this_thread::sleep_for(std::chrono::milliseconds(300)); } std::string Scanner::GetSysInfo() { meminfo = MemoryInfo::GetInstance(); LOG(" GetSysInfo-------- \n"); auto scannerinfo = GetScanInfo(); auto fwverion = mapFradme_SP[scannerinfo.SpeedMode].FWVERSIO; ScannerSysInfo info = { .CPU = SCPU::CPU_3288, .Systype = SysType::Sys_Linux_Debian, .Screentype = ScreenType::ST_None, .MtBoardVersion = 0x20220114, .MtType = GetSMBType(), .FPGAVersion = m_fpga->read(15), .Cistype = (HGCISType)GetCisType(), .ResSup = {200, 300, 0}, .MemTotal = 0, .DiskTotal = 100, .DiskUsed = 0, .KernelVersion = "", .Have_EthernPort = 0, .ServiceVersion = fwverion, .UsbProtocol = 1.0}; LOG("FPGAVersion=%08x \n",info.FPGAVersion); m_scansysinfo.reset(new SysInforTool(info)); return m_scansysinfo->GetSysInfo(); }