zynq_7010/Scanner.cpp

464 lines
13 KiB
C++
Raw Normal View History

2023-07-17 03:29:37 +00:00
#include "Scanner.h"
#include <iostream>
#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<FpgaComm>();
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<Sensor>(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 = 3;
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<InitState>::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);
int tmp_recordScannum = 0;
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))
{
// isPaperInit = false;
// this_thread::sleep_for(std::chrono::milliseconds(200));
LOG("\n ----------------EXIT 0000000000 cnt=%d---------------- \n",m_DstScannum);
put(S_EVT_STOP_SCAN);
LOG("STOP STOP STOP RUNSCAN \n");
writesyslog(LOG_INFO, getmeminfo());
writesyslog(LOG_INFO, "no paper scanner stop scan\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");
writesyslog(LOG_INFO, getmeminfo());
writesyslog(LOG_INFO, "no paper scanner stop scan\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();
2023-07-17 03:29:37 +00:00
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");
writesyslog(LOG_INFO, "paper jam out error\n");
}
else
{
// m_glue.m_deviceevent(16); //双张
// LOG("paper 双张了。。。。。\n");
m_scaninfo.DoubleNum++;
writesyslog(LOG_INFO, "paper double paper error\n");
}
capturer->stopsnap(b_autosize);
capturer->waitsnapdone(1);//等待采集完成
this_thread::sleep_for(std::chrono::milliseconds(500));//200 80ms 600 260ms
2023-07-17 03:29:37 +00:00
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->stopsnap(b_autosize);
capturer->waitsnapdone(1);//等待采集完成
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
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++;
tmp_recordScannum++;
writesyslog(LOG_INFO, getmeminfo());
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;
}
}
}
// motorCuozhi.stop();
// motorZouzhi.stop();
// auto js = GetScanInfoFromJson();
// m_scaninfo.SleepTime = js.SleepTime;
m_DstScannum = 0;
sensor->enableDoubleSensor(false);
sensor->resetPaperPin();
capturer->setScanFlag(false);
capturer->close();
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);
LOG("\n--------------------------scan done --------------------------------\n");
std::string loginfo = "current scan session scanned " + to_string(tmp_recordScannum) + " page paper\n";
writesyslog(LOG_INFO, loginfo);
}
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();
}