diff --git a/device/gxx-linux/capimage/CImageMerge.cpp b/device/gxx-linux/capimage/CImageMerge.cpp new file mode 100644 index 0000000..a7d5f53 --- /dev/null +++ b/device/gxx-linux/capimage/CImageMerge.cpp @@ -0,0 +1,75 @@ +#include "CImageMerge.h" + +CImageMerge::CImageMerge() +{ +} +CImageMerge::~CImageMerge() +{ +} +cv::Mat CImageMerge::MergeImage(cv::Mat &srcMat, int dstwidth, int dstheight) +{ + cv::Mat retMat(dstheight, dstwidth, CV_8UC3); + + if (!srcMat.empty()) + { + std::vector ch_mats; + int blockcnt = 12; + int spitWidth = srcMat.cols / blockcnt; + + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 3; j++) + { + std::cout << " index " << (i * 3 + j) << " x " << spitWidth * (i * 3 + j) << " y " << 0 << " width " << spitWidth << " height " << dstheight << std::endl; + ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + j), 0, spitWidth, dstheight))); + } + cv::merge(ch_mats, retMat(cv::Rect(spitWidth * i, 0, spitWidth, dstheight))); + ch_mats.clear(); + } + return retMat; + } +} + +cv::Mat CImageMerge::MergeImage(bool iscolor, cv::Mat &srcMat, int dstwidth, int dstheight,std::uint32_t fpga_vs) +{ + int blockcnt = 12; + int spitWidth = srcMat.cols / blockcnt; + int abortwidth; // = spitWidth == 3888 ? 432 : (spitWidth == 2592 ? 216 : 144); + if (!iscolor) //灰度 + { + abortwidth = spitWidth == 1296 ? 432 : (spitWidth == 648 ? 216 : 144); + } + else + { + abortwidth = spitWidth == 3888 ? 432 : (spitWidth == 1944 ? 216 : 144); + } + + cv::Mat dst(dstheight, dstwidth - abortwidth * 2, CV_8UC(iscolor ? 3 : 1)); + if (!iscolor) + { + for (int i = 0; i < 2; i++) + { + srcMat(cv::Rect((dstwidth / 2 + abortwidth) * i, 0, dstwidth / 2 - abortwidth, dstheight)).copyTo(dst(cv::Rect(dst.cols / 2 * i, 0, dst.cols / 2, dstheight))); + } + srcMat.release(); + } + else + { + std::vector m_splits; + std::vector m_index = {0, 3, 8, 11, 2, 5, 6, 9, 1, 4, 7, 10}; + for (int i = 0; i < 3; i++) + { + int startindex = i == 0 ? 0 : (i == 1 ? 4 : 8); + cv::Mat t_mat(dstheight, dstwidth - abortwidth * 2, CV_8UC1); + srcMat(cv::Rect(spitWidth * m_index[startindex + 0], 0, spitWidth, dstheight)).copyTo(t_mat(cv::Rect(0, 0, spitWidth, dstheight))); + srcMat(cv::Rect(spitWidth * m_index[startindex + 1], 0, spitWidth - abortwidth, dstheight)).copyTo(t_mat(cv::Rect(spitWidth, 0, spitWidth - abortwidth, dstheight))); + srcMat(cv::Rect(spitWidth * m_index[startindex + 2] + abortwidth, 0, spitWidth - abortwidth, dstheight)).copyTo(t_mat(cv::Rect(spitWidth * 2 - abortwidth, 0, spitWidth - abortwidth, dstheight))); + srcMat(cv::Rect(spitWidth * m_index[startindex + 3], 0, spitWidth, dstheight)).copyTo(t_mat(cv::Rect(spitWidth * 3 - abortwidth * 2, 0, spitWidth, dstheight))); + m_splits.push_back(t_mat); + } + cv::merge(m_splits, dst); + m_splits.clear(); + } + srcMat.release(); + return dst; +} \ No newline at end of file diff --git a/device/gxx-linux/capimage/CImageMerge.h b/device/gxx-linux/capimage/CImageMerge.h new file mode 100644 index 0000000..e93214e --- /dev/null +++ b/device/gxx-linux/capimage/CImageMerge.h @@ -0,0 +1,14 @@ +#pragma once +#include + +class CImageMerge +{ +private: + /* data */ +public: + CImageMerge(/* args */); + ~CImageMerge(); +public: + cv::Mat MergeImage(cv::Mat& srcMat,int dstwidth,int dstheight); + cv::Mat MergeImage(bool iscolor,cv::Mat& srcMat,int dstwidth,int dstheight,std::uint32_t fpga_vs); +}; diff --git a/device/gxx-linux/capimage/CameraParam.h b/device/gxx-linux/capimage/CameraParam.h new file mode 100644 index 0000000..789e6a3 --- /dev/null +++ b/device/gxx-linux/capimage/CameraParam.h @@ -0,0 +1,40 @@ +#pragma once +#include + + +#define LIGHT_DIFF(maxthre, x) ((maxthre)-x) +#define BLACK_DIFF(x) (8 - x) +#define FMT_STEP(x) \ + do \ + { \ + if (x < 1 && x > 0) \ + { \ + x = 1; \ + } \ + if (step < 0 && step > -1) \ + { \ + x = -1; \ + } \ + } while (0) + + +struct FPGAConfigParam +{ + unsigned int ExposureF[3]; //RGB + unsigned int GainF[6]; //123456 + unsigned int OffsetF[6]; //123456 + unsigned int ExposureB[3]; //RGB + unsigned int GainB[6]; //123456 + unsigned int OffsetB[6]; //123456 + unsigned int DpiMode; + unsigned int ColorMode; + unsigned int MaxBright; + unsigned int MaxExp; + unsigned int Sp; + unsigned int HRatio; + unsigned int VRatio; + std::string LutPath; + std::string TextLutPath; + std::string Flat_BwPath; + std::string Flat_WhitePath; +}; \ No newline at end of file diff --git a/device/gxx-linux/capimage/Capturer.cpp b/device/gxx-linux/capimage/Capturer.cpp index dc5cf06..0fa1f3a 100644 --- a/device/gxx-linux/capimage/Capturer.cpp +++ b/device/gxx-linux/capimage/Capturer.cpp @@ -14,6 +14,8 @@ #include #include #include "filetools.h" +#include "CameraParam.h" +#include "correct_ultis.h" using namespace std; #define LOG_PATH "/usr/local/correct.log" @@ -22,65 +24,14 @@ FileTools ft(LOG_PATH); static std::string loggername = "Capturer"; bool isAutoCorrect = true; -int offsetStep[12]; -int expStep[2][3]; -double radio = 1; +double Radio = 1; cv::Mat mBuffMat; cv::Mat out; -#define LIGHT_DIFF(maxthre, x) ((maxthre)-x) -#define BLACK_DIFF(x) (10 - x) -#define FMT_STEP(x) \ - do \ - { \ - if (x < 1 && x > 0) \ - { \ - x = 1; \ - } \ - if (step < 0 && step > -1) \ - { \ - x = -1; \ - } \ - } while (0) - -void initStep() -{ - for (int i = 0; i < 12; i++) - { - offsetStep[i] = 256; - } - for (int i = 0; i < 2; i++) - { - for (int j = 0; j < 3; j++) - { - expStep[i][j] = 1200; - } - } -} - -//设置一面的offset值 -void setOffset(int *config, int step) -{ - for (int i = 0; i < 6; i++) - { - int *offset = config + i; - *offset += step; - if (*offset < 0) - *offset = 1; - if (*offset > 255) - *offset = 255; - } -} - Capturer::Capturer() - : vdd_cis_3voff_pin(new GpioOut(CIS_3v3_Off)), - vdd_vis_5ven_pin(new GpioOut(CIS_5v_En)), - reset_pin(new GpioOut(Fpga_Reset)), - image_in_transfer_pin(new Gpio(Image_In_Transfer)), - initDone_pin(new Gpio(Fpga_InitDone)), - fpgaLoad(new Gpio(70)), - fpga_conf_done(new Gpio(69)),//gpio init 导出 scanservice 仅操作IO - fpga_conf_initn(new Gpio(71)),//gpio init 导出 scanservice 仅操作IO + : reset_pin(new GpioOut(Fpga_Reset)), + initDone_pin(new Gpio(71)), + fpgaLoad(new GpioOut(70)), bcorrecting(false) { LOG_INIT(); @@ -94,12 +45,6 @@ Capturer::Capturer() Capturer::~Capturer() { - -} - -void Capturer::Fpga_regsAccess_reset(bool enable){ - if(fpgaComm.get()) - fpgaComm->regsAccess_reset(enable); } void Capturer::open() @@ -144,7 +89,7 @@ void Capturer::open() } static int val = 0; static double exp_ratio = 0.1; -void Capturer::open(HGScanConfig config) +void Capturer::open(HGScanConfig config,FPGAConfigParam fpgaparam) { if (val > 4000) val = 0; @@ -152,8 +97,7 @@ void Capturer::open(HGScanConfig config) if (exp_ratio > 2.0) exp_ratio = 0.1; cisconfigs = getcisparams(); - auto hgsize = papersMap[(PaperSize)config.g200params.paper]; - int height = hgsize.height; + int height = 1632; fpgaComm->setColorMode(config.g200params.color ? 1 : 0); auto info = jsonconfig().getscannerinfo(); //set_sp(config.g200params.color ? cisconfigs.color.sp : cisconfigs.gray.sp); //0x03fa : 0x0bf0 @@ -176,11 +120,10 @@ void Capturer::open(HGScanConfig config) clrsp=info.color_sp; graysp = info.gray_sp; set_sp(config.g200params.color ? clrsp : graysp); - HG_LOG("\n capture color sp =%d, gray sp =%d",clrsp,graysp); + printf("\n capture color sp =%d, gray sp =%d",clrsp,graysp); //set_sp(config.g200params.color ? 0x335 : 0x99f); //G100 0x438 0xca8 60 ppm 0x335 : 0x99f 100ppm //G200 SP极限值205 0x27c 0x775 140ppm - //fpgaComm->setDpi(config.g200params.dpi); //0 300dpi 1 200dpi - fpgaComm->setDpi(1); + fpgaComm->setDpi(config.g200params.dpi); //0 300dpi 1 200dpi fpgaComm->setSample(256); fpgaComm->enableLed(true); //设置曝光值等 @@ -209,7 +152,6 @@ void Capturer::close() { video->close(); } - fpga_reload(); } void Capturer::start() { @@ -256,15 +198,15 @@ void Capturer::fpga_reset() std::this_thread::sleep_for(std::chrono::milliseconds(50)); } -// void Capturer::fpga_reload() -// { -// //fpga 代码重载 -// fpgaLoad->setValue(Gpio::Low); -// std::this_thread::sleep_for(std::chrono::milliseconds(15)); -// fpgaLoad->setValue(Gpio::High); -// std::this_thread::sleep_for(std::chrono::milliseconds(15)); -// fpgaComm->resetADC(); -// } +void Capturer::fpga_reload() +{ + //fpga 代码重载 + fpgaLoad->setValue(Gpio::Low); + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + fpgaLoad->setValue(Gpio::High); + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + fpgaComm->resetADC(); +} void Capturer::set_expo(int ix, int val) { @@ -358,11 +300,12 @@ void Capturer::configFPGAParam(bool iscorrect, int mode) // val+=step; // exp_ratio += 0.1; + // printf("\n\n\n----------------\n"); // for (int i = 0; i < 2; i++) // { // for (int j = 0; j < 6; j++) // { - + // offsets[i][j]=j==4?200:0; // printf("gains[%d][%d] = %d \r\n", i, j, gains[i][j]); // printf("offsets[%d][%d] = %d \r\n", i, j, offsets[i][j]); // if (j < 3) @@ -472,7 +415,7 @@ void Capturer::autocorrect(int colormode) m_captureCallback(4, colormode ? "------彩色校正完成------\r\n" : "------灰度校正完成------\r\n"); reset(); bcorrecting = false; - HG_LOG("init_autocorrect exit \n"); + printf("init_autocorrect exit \n"); } void Capturer::creatcorrectconfig(int mode) @@ -515,7 +458,7 @@ void Capturer::creatcorrectconfig(int mode) ft.append_log(log); std::this_thread::sleep_for(std::chrono::milliseconds(100)); fpgaComm->enableLed(true); - fpgaComm->update(); + //fpgaComm->update(); std::this_thread::sleep_for(std::chrono::milliseconds(200)); fpgaComm->capture(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); @@ -567,7 +510,7 @@ bool Capturer::saveLutImg(int mode, int index) void *data = video->read_frame(1500); if (data == NULL) { - log = "图像采集失败!\r\n"; + log = "图像采集失败!\r\n"; ft.append_log(log); isNeedSave = false; if (m_captureCallback) @@ -631,7 +574,7 @@ bool Capturer::saveLutImg(int mode, int index) int diff = LIGHT_DIFF(scannerinfo.clr_maxbright, *((double *)values + k)); log += " 明场:" + std::to_string(k) + ";diff:" + std::to_string(diff) + "\r\n"; - double step = diff * radio; + double step = diff * Radio; int preStep = *((int *)expStep + k); if (step * preStep < 0) { @@ -643,7 +586,7 @@ bool Capturer::saveLutImg(int mode, int index) isOutBounds |= exposures[x] <= 0 && step < 0; if (isOutBounds) log += " 第" + to_string(x) + "个明场校正异常 \r\n"; - else if (abs(diff) >= 2 || isMinStep) + else if (abs(diff) >= 1 || isMinStep) { *((int *)expStep + k) = (int)(step); exposures[x] += step; @@ -677,7 +620,7 @@ bool Capturer::saveLutImg(int mode, int index) { int k = s * 6 + j; double diff = BLACK_DIFF(offValues[k]); - double step = radio * diff; + double step = Radio * diff; int preStep = offsetStep[k]; if (step * preStep < 0) { @@ -685,7 +628,7 @@ bool Capturer::saveLutImg(int mode, int index) } else { - radio = 1; + Radio = 1; } FMT_STEP(step); bool isMinStep = abs(step) == 1 && step == offsetStep[k]; @@ -787,7 +730,7 @@ bool Capturer::saveLutImg(int mode, int index) { int *exposures = (int *)(s == 0 ? cisconfigs.grayCorrect.expF : cisconfigs.grayCorrect.expB); int diff = LIGHT_DIFF(scannerinfo.gray_maxbright, values[s]); - double step = diff * radio; + double step = diff * Radio; log += " 明场:" + to_string(s) + ";diff:" + to_string(diff) + "\r\n"; int preStep = expStep[s][0]; if (step * preStep < 0) @@ -796,7 +739,7 @@ bool Capturer::saveLutImg(int mode, int index) } else { - radio = 1; + Radio = 1; } FMT_STEP(step); @@ -808,7 +751,7 @@ bool Capturer::saveLutImg(int mode, int index) isOutBounds |= exp <= 0 && step < 0; if (isOutBounds) log += " 第" + to_string(s) + "个明场校正异常 \r\n"; - else if (abs(diff) > 2 || isMinStep) + else if (abs(diff) > 1 || isMinStep) { exp += step; if (exp < 0) @@ -843,7 +786,7 @@ bool Capturer::saveLutImg(int mode, int index) { int k = s * 6 + j; double diff = BLACK_DIFF(offValues[k]); - double step = radio * diff; + double step = Radio * diff; int preStep = offsetStep[k]; if (step * preStep < 0) { @@ -851,7 +794,7 @@ bool Capturer::saveLutImg(int mode, int index) } else { - radio = 1; + Radio = 1; } FMT_STEP(step); bool isMinStep = abs(step) == 1 && step == offsetStep[k]; @@ -892,25 +835,4 @@ bool Capturer::saveLutImg(int mode, int index) } } return isNeedSave; -} - -void Capturer::fpga_reload() -{ - // fpga 代码重载 - fpgaLoad->setValue(Gpio::Low); - std::this_thread::sleep_for(std::chrono::milliseconds(15)); - fpga_conf_initn->setValue(Gpio::Low); - std::this_thread::sleep_for(std::chrono::milliseconds(15)); - printf("\n fpga_conf_done value %d",fpga_conf_done->getValue()); - fpgaLoad->setValue(Gpio::High); - std::this_thread::sleep_for(std::chrono::milliseconds(15)); - fpga_conf_initn->setValue(Gpio::High); - //std::this_thread::sleep_for(std::chrono::milliseconds(5)); - printf("\n fpga_conf_done value %d",fpga_conf_done->getValue()); - // while(fpga_conf_done->getValue() == Gpio::GpioLevel::Low) - // std::this_thread::sleep_for(std::chrono::milliseconds(5)); - std::this_thread::sleep_for(std::chrono::seconds(3)); - printf("\n fpga_conf_done value %d",fpga_conf_done->getValue()); - fpgaComm->resetADC(); - fpgaComm->update(); } \ No newline at end of file diff --git a/device/gxx-linux/capimage/Capturer.h b/device/gxx-linux/capimage/Capturer.h index 9f760ec..3df8c93 100644 --- a/device/gxx-linux/capimage/Capturer.h +++ b/device/gxx-linux/capimage/Capturer.h @@ -1,58 +1,26 @@ #pragma once -#include -#include -#include -#include "regsaccess.h" -#include "commondef.h" +#include #include "hgutils.h" class FpgaComm; class gVideo; class Gpio; -class ICapturer -{ -public: - virtual ~ICapturer() {} - virtual void open() = 0; - virtual void Fpga_regsAccess_reset(bool enable) = 0 ; - virtual void open(HGScanConfig config) = 0; - virtual void close() = 0; - virtual void start() = 0; - virtual void stop() = 0; - virtual bool is_runing() = 0; - virtual void snap() = 0; - - virtual void set_size(int width, int height) = 0; - virtual void* readFrame(int timeout) = 0; - - virtual void set_gain(int ix, int val) = 0; - virtual void set_offset(int ix, int val) = 0; - virtual void set_expo(int ix, int val) = 0; - - virtual std::shared_ptr regs() = 0; - virtual void reset() = 0; - virtual int width() = 0; - virtual int height() = 0; - virtual int color() = 0; - virtual void init_autocorrect(int colormode) = 0; - virtual void setcapturecall(std::function callback) = 0; -}; - class Capturer : public ICapturer { public: Capturer(); virtual ~Capturer(); - virtual void Fpga_regsAccess_reset(bool enable); + virtual void open(); - virtual void open(HGScanConfig config); + virtual void open(HGScanConfig config,FPGAConfigParam fpgaparam); virtual void close(); virtual void start(); virtual void stop(); virtual bool is_runing(); virtual void snap(); - + virtual void stopsnap(){} + virtual int getautosizeheight(){return 0;} virtual void set_size(int width, int height); virtual void set_sp(int sp); @@ -89,8 +57,6 @@ private: std::shared_ptr image_in_transfer_pin; std::shared_ptr initDone_pin; std::shared_ptr fpgaLoad; - std::shared_ptr fpga_conf_initn; - std::shared_ptr fpga_conf_done; std::shared_ptr fpgaComm; std::shared_ptr video; diff --git a/device/gxx-linux/capimage/CorrectParam.cpp b/device/gxx-linux/capimage/CorrectParam.cpp new file mode 100644 index 0000000..bc51dc6 --- /dev/null +++ b/device/gxx-linux/capimage/CorrectParam.cpp @@ -0,0 +1,279 @@ +#include "CorrectParam.h" +#include +#include +#include +#include +#include +#include "commondef.h" + +using namespace std; + +#define JSONPATH "/usr/local/huago/cameraparam.json" + +#define TEXTLUT200COLORPATH "/usr/local/huago/Textlut200clr.bmp" +#define LUT200COLORPATH "/usr/local/huago/lut200clr.bmp" +#define LUT200_COLOR_BLACKPATH "/usr/local/huago/lut200clrbw.bmp" +#define LUT200_COLOR_WHITEPATH "/usr/local/huago/lut200clrwhite.bmp" + +#define TEXTLUT200GRAYPATH "/usr/local/huago/Textlut200gray.bmp" +#define LUT200GRAYPATH "/usr/local/huago/lut200gray.bmp" +#define LUT200_GRAY_BLACKPATH "/usr/local/huago/lut200graybw.bmp" +#define LUT200_GRAY_WHITEPATH "/usr/local/huago/lut200graywhite.bmp" + +#define TEXTLUT300COLORPATH "/usr/local/huago/Textlut300clr.bmp" +#define LUT300COLORPATH "/usr/local/huago/lut300clr.bmp" +#define LUT300_COLOR_BLACKPATH "/usr/local/huago/lut300clrbw.bmp" +#define LUT300_COLOR_WHITEPATH "/usr/local/huago/lut300clrwhite.bmp" + +#define TEXTLUT300GRAYPATH "/usr/local/huago/Textlut300gray.bmp" +#define LUT300GRAYPATH "/usr/local/huago/lut300gray.bmp" +#define LUT300_GRAY_BLACKPATH "/usr/local/huago/lut300graybw.bmp" +#define LUT300_GRAY_WHITEPATH "/usr/local/huago/lut300graywhite.bmp" + +#define LUT600COLORPATH "/usr/local/huago/lut600clr.bmp" +#define TEXTLUT600COLORPATH "/usr/local/huago/Textlut600clr.bmp" +#define LUT600_COLOR_BLACKPATH "/usr/local/huago/lut600clrbw.bmp" +#define LUT600_COLOR_WHITEPATH "/usr/local/huago/lut600clrwhite.bmp" + +#define LUT600GRAYPATH "/usr/local/huago/lut600gray.bmp" +#define TEXTLUT600GRAYPATH "/usr/local/huago/Textlut600gray.bmp" +#define LUT600_GRAY_BLACKPATH "/usr/local/huago/lut600graybw.bmp" +#define LUT600_GRAY_WHITEPATH "/usr/local/huago/lut600graywhite.bmp" + +CorrectParam::CorrectParam() +{ + initdefaultpapram(); +} + +CorrectParam::~CorrectParam() +{ +} + +std::vector CorrectParam::GetCorrectParams() +{ + std::ifstream i(JSONPATH); + json j; + i >> j; + std::vector vct_param; + for (json::iterator it = j.begin(); it != j.end(); ++it) + { + auto tmv = it.value(); + FPGAConfigParam param; + from_json(tmv, param); + vct_param.push_back(param); + } + return vct_param; +} + +FPGAConfigParam CorrectParam::GetFpgaparam(int dpi,int mode) +{ + FPGAConfigParam param; + auto filejson = GetCorrectParams(); + for (size_t i = 0; i < filejson.size(); i++) + { + if ((filejson[i].ColorMode == mode) && + (filejson[i].DpiMode == dpi)) + { + param = filejson[i]; + break; + } + } + return param; +} + +void CorrectParam::SaveCorrectParam(FPGAConfigParam& parms) +{ + auto filejson = GetCorrectParams(); + for (size_t i = 0; i < filejson.size(); i++) + { + if ((filejson[i].ColorMode == parms.ColorMode) && + (filejson[i].DpiMode == parms.DpiMode)) + { + memcpy(filejson[i].ExposureB, parms.ExposureB, sizeof(parms.ExposureB)); + memcpy(filejson[i].ExposureF, parms.ExposureF, sizeof(parms.ExposureF)); + memcpy(filejson[i].GainB, parms.GainB, sizeof(parms.GainB)); + memcpy(filejson[i].GainF, parms.GainF, sizeof(parms.GainF)); + memcpy(filejson[i].OffsetB, parms.OffsetB, sizeof(parms.OffsetB)); + memcpy(filejson[i].OffsetF, parms.OffsetF, sizeof(parms.OffsetF)); + filejson[i].LutPath = parms.LutPath; + filejson[i].TextLutPath = parms.TextLutPath; + filejson[i].Flat_BwPath = parms.Flat_BwPath; + filejson[i].Flat_WhitePath = parms.Flat_WhitePath; + filejson[i].Sp = parms.Sp; + filejson[i].HRatio = parms.HRatio; + filejson[i].VRatio = parms.VRatio; + break; + } + } + json j = json::array(); + for (size_t i = 0; i < filejson.size(); i++) + { + json t_j; + to_json(t_j, filejson[i]); + j.push_back(t_j); + } + ofstream ofs(JSONPATH); + ofs << std::setw(4) << j << std::endl; +} + +void CorrectParam::initdefaultpapram() +{ + struct stat buff; + if (stat(JSONPATH, &buff) != 0)//存在 + { + json js = json::array(); + { + FPGAConfigParam param; + json t_j; + + //彩色 300 dpi + param.ColorMode = 1;//彩色 + param.DpiMode = 2;//300 dpi +#ifdef G200 + param.MaxBright = 190; +#else + param.MaxBright = 200; +#endif + param.MaxExp = 1100; + param.HRatio = 1065353216; + param.VRatio = 1065353216; + param.LutPath = LUT300COLORPATH; + param.TextLutPath = TEXTLUT300COLORPATH; + param.Flat_BwPath = LUT300_COLOR_BLACKPATH; + param.Flat_WhitePath = LUT300_COLOR_WHITEPATH; + param.Sp = 1200; + for (size_t i = 0; i < 6; i++) + { + if(i<3) + param.ExposureB[i] = param.ExposureF[i] = 700;//1500 + param.GainF[i] = param.GainB[i] = 170; + param.OffsetF[i] = param.OffsetB[i] = 125; + + } + to_json(t_j, param); + js.push_back(t_j); + + //灰度 300 dpi + param.ColorMode = 0;//灰度 + param.MaxBright = 200; + param.LutPath = LUT300GRAYPATH; + param.TextLutPath = TEXTLUT300GRAYPATH; + param.Flat_BwPath = LUT300_GRAY_BLACKPATH; + param.Flat_WhitePath = LUT300_GRAY_WHITEPATH; + to_json(t_j, param); + js.push_back(t_j); + + //彩色 200 dpi +#ifdef G200 + param.MaxBright = 190; +#else + param.MaxBright = 200; +#endif + param.ColorMode = 1;//彩色 + param.DpiMode = 1;//200 dpi + param.LutPath = LUT200COLORPATH; + param.TextLutPath = TEXTLUT200COLORPATH; + param.Flat_BwPath = LUT200_COLOR_BLACKPATH; + param.Flat_WhitePath = LUT200_COLOR_WHITEPATH; + for (size_t i = 0; i < 6; i++) + { + if(i<3) + param.ExposureB[i] = param.ExposureF[i] = 650;//1500 + param.GainF[i] = param.GainB[i] = 170; + param.OffsetF[i] = param.OffsetB[i] = 125; + } + to_json(t_j, param); + js.push_back(t_j); + + //灰度 200dpi + param.MaxBright = 200; + param.ColorMode = 0;//灰度 + param.LutPath = LUT200GRAYPATH; + param.TextLutPath = TEXTLUT200GRAYPATH; + param.Flat_BwPath = LUT200_GRAY_BLACKPATH; + param.Flat_WhitePath = LUT200_GRAY_WHITEPATH; + to_json(t_j, param); + js.push_back(t_j); + + //彩色 600 dpi +#ifdef G200 + param.MaxBright = 190; +#else + param.MaxBright = 200; +#endif + param.ColorMode = 1;//彩色 + param.DpiMode = 0x03;//200 dpi + param.LutPath = LUT600COLORPATH; + param.TextLutPath = TEXTLUT600COLORPATH; + param.Flat_BwPath = LUT600_COLOR_BLACKPATH; + param.Flat_WhitePath = LUT600_COLOR_WHITEPATH; + for (size_t i = 0; i < 6; i++) + { + if(i<3) + param.ExposureB[i] = param.ExposureF[i] = 1350;//1500 + param.GainF[i] = param.GainB[i] = 170; + param.OffsetF[i] = param.OffsetB[i] = 125; + + } + to_json(t_j, param); + js.push_back(t_j); + + + //灰度 600dpi + param.MaxBright = 200; + param.ColorMode = 0;//灰度 + param.LutPath = LUT600GRAYPATH; + param.TextLutPath = TEXTLUT600GRAYPATH; + param.Flat_BwPath = LUT600_GRAY_BLACKPATH; + param.Flat_WhitePath = LUT600_GRAY_WHITEPATH; + to_json(t_j, param); + js.push_back(t_j); + + std::ofstream ofs(JSONPATH); + ofs << std::setw(4) << js << std::endl; + } + } +} + +void CorrectParam::to_json(json& j, FPGAConfigParam& param) +{ + j = json{ {"ExposureF",param.ExposureF}, + {"GainF",param.GainF}, + {"OffsetF",param.OffsetF}, + {"ExposureB",param.ExposureB}, + {"GainB",param.GainB}, + {"OffsetB",param.OffsetB}, + {"DpiMode",param.DpiMode}, + {"ColorMode",param.ColorMode}, + {"MaxBright",param.MaxBright}, + {"MaxExp",param.MaxExp}, + {"Sp",param.Sp}, + {"HRatio",param.HRatio}, + {"VRatio",param.VRatio}, + {"LutPath",param.LutPath}, + {"TextLutPath",param.TextLutPath}, + {"FlatBlackPath",param.Flat_BwPath}, + {"FlatWhitePath",param.Flat_WhitePath} + }; +} + +void CorrectParam::from_json(json& j, FPGAConfigParam& param) +{ + j.at("ExposureF").get_to(param.ExposureF); + j.at("GainF").get_to(param.GainF); + j.at("OffsetF").get_to(param.OffsetF); + j.at("ExposureB").get_to(param.ExposureB); + j.at("GainB").get_to(param.GainB); + j.at("OffsetB").get_to(param.OffsetB); + j.at("DpiMode").get_to(param.DpiMode); + j.at("ColorMode").get_to(param.ColorMode); + j.at("MaxBright").get_to(param.MaxBright); + j.at("MaxExp").get_to(param.MaxExp); + j.at("Sp").get_to(param.Sp); + j.at("HRatio").get_to(param.HRatio); + j.at("VRatio").get_to(param.VRatio); + j.at("LutPath").get_to(param.LutPath); + j.at("TextLutPath").get_to(param.TextLutPath); + j.at("FlatBlackPath").get_to(param.Flat_BwPath); + j.at("FlatWhitePath").get_to(param.Flat_WhitePath); +} \ No newline at end of file diff --git a/device/gxx-linux/capimage/CorrectParam.h b/device/gxx-linux/capimage/CorrectParam.h new file mode 100644 index 0000000..185b2aa --- /dev/null +++ b/device/gxx-linux/capimage/CorrectParam.h @@ -0,0 +1,21 @@ +#pragma once +#include "json.hpp" +#include +#include +#include "CameraParam.h" + +using json = nlohmann::json; + +class CorrectParam +{ +public: + CorrectParam(/* args */); + ~CorrectParam(); + FPGAConfigParam GetFpgaparam(int dpi,int mode); + void SaveCorrectParam(FPGAConfigParam& parms); +private: + void initdefaultpapram(); + std::vector GetCorrectParams(); + void to_json(json& j, FPGAConfigParam& param); + void from_json(json& j, FPGAConfigParam& param); +}; diff --git a/device/gxx-linux/capimage/FpgaComm.cpp b/device/gxx-linux/capimage/FpgaComm.cpp index 8f1ac70..0c88f22 100644 --- a/device/gxx-linux/capimage/FpgaComm.cpp +++ b/device/gxx-linux/capimage/FpgaComm.cpp @@ -17,13 +17,26 @@ FpgaComm::FpgaComm() { - m_regsAccess.reset(new UartRegsAccess(FPGA_UART, 921600, 0x03, 0x83)); - update(); + m_regsAccess.reset(new UartRegsAccess(MOTOR_UART, 921600, 0x03, 0x83)); + update(0); Reg(AledR).sample = 256; WR_Reg(AledR); + } +void FpgaComm::regsAccess_reset(bool enable){ + if(enable) + { + if(!m_regsAccess.get()) + m_regsAccess.reset(new UartRegsAccess(MOTOR_UART, 921600, 0x03, 0x83)); + update(0); + return; + } + if(m_regsAccess.get()) + m_regsAccess.reset(); +} + bool FpgaComm::read(unsigned int addr, unsigned int& val) { return m_regsAccess->read(addr, val); } @@ -32,18 +45,6 @@ bool FpgaComm::write(unsigned int addr, unsigned int val) { return m_regsAccess->write(addr, val); } -void FpgaComm::regsAccess_reset(bool enable){ - if(enable) - { - if(!m_regsAccess.get()) - m_regsAccess.reset(new UartRegsAccess(FPGA_UART, 921600, 0x03, 0x83)); - update(); - return; - } - if(m_regsAccess.get()) - m_regsAccess.reset(); -} - void FpgaComm::setFrameHeight(int height){ Reg(frame).height = height; WR_Reg(frame); @@ -66,7 +67,7 @@ void FpgaComm::enableLed(bool bEnable) { Reg(BledR).ledEnable = bEnable; WR_Reg(BledR); #else - Reg(BledR).ledEnable = bEnable; + Reg(BledR).ledEnable = !bEnable; WR_Reg(BledR); #endif } @@ -275,12 +276,13 @@ void FpgaComm::setDelayTime(int value) { WR_Reg(DelayTime); } -void FpgaComm::update() +void FpgaComm::update(int times) { - for(int i = 0; i < MAX_REGS; i++) + std::uint32_t tmp_reg = 0; + for(int i = 0; i < 16; i++) { - read(i, fpgaParams.regs[i]); - printf("reg[%d] = 0x%08x \n",i,fpgaParams.regs[i]); + read(i, tmp_reg); + printf("times[%d] reg[%d] = 0x%08x \n",times,i,tmp_reg); } } @@ -358,4 +360,31 @@ void FpgaComm::resetADC() { WR_Reg(mode); fpgaParams.mode.adcB = 0; WR_Reg(mode); +} + + +void FpgaComm::setEnTestCol(bool en) +{ + Reg(AledR).en_test_color = en?1:0; + WR_Reg(AledR); +} + +void FpgaComm::setEnTestBit(bool en) +{ + Reg(AledR).en_test = en?1:0; + WR_Reg(AledR); +} + +void FpgaComm::setVsp(unsigned int Aside,unsigned int BSide) +{ + unsigned int regv; + CISVSP vsp; + read(13,regv); + vsp.value = regv; + vsp.bits.ASide_VSP = Aside; + vsp.bits.BSide_VSP = BSide; + vsp.bits.reserved=0; + printf("setVsp A side =%d B side=%d vspint=%08x \n", vsp.bits.ASide_VSP, vsp.bits.BSide_VSP,vsp.value); + write(13,vsp.value); + WR_Reg(AledR); } \ No newline at end of file diff --git a/device/gxx-linux/capimage/FpgaComm.h b/device/gxx-linux/capimage/FpgaComm.h index 4b2a0c7..9e5df19 100644 --- a/device/gxx-linux/capimage/FpgaComm.h +++ b/device/gxx-linux/capimage/FpgaComm.h @@ -6,7 +6,7 @@ #ifdef HAS_UV #define MAX_REGS 0x0e #else -#define MAX_REGS 0x0d +#define MAX_REGS 0x0e #endif typedef struct Frame_FPGA @@ -75,7 +75,9 @@ typedef struct CIS_LED_R { unsigned short int ledEnable : 1; unsigned short int sample : 9; - unsigned short int reserved : 6; + unsigned short int en_test_color :1; + unsigned short int en_test : 1; + unsigned short int reserved : 4; unsigned short int ledR; } CisLedR; @@ -91,6 +93,8 @@ typedef struct CIS_LED_UV unsigned short int ledBSide; } CisLedUv; + + typedef union Fpga_Params { struct @@ -118,6 +122,17 @@ typedef union Fpga_Params } FpgaParams; +typedef union CIS_VSP +{ + struct + { + unsigned int ASide_VSP:8; + unsigned int BSide_VSP:8; + unsigned int reserved : 16; + } bits; + int value; +} CISVSP; + class FpgaComm : public IRegsAccess { public: @@ -149,6 +164,9 @@ public: void setBExposureB(int value); void setBExpousreUV(int value); + void setEnTestCol(bool en); + void setEnTestBit(bool en); + void setSp(int value); int getSp(); @@ -168,9 +186,10 @@ public: void setDelayTime(int value); void setTrigMode(bool isArmMode); - void update(); + void update(int times); void enableJamCheck(bool b); void resetADC(); + void setVsp(unsigned int Aside,unsigned int BSide); virtual bool write(unsigned int addr, unsigned int val); virtual bool read(unsigned int addr, unsigned int& val); diff --git a/device/gxx-linux/capimage/ICapturer.h b/device/gxx-linux/capimage/ICapturer.h new file mode 100644 index 0000000..dbb3c5e --- /dev/null +++ b/device/gxx-linux/capimage/ICapturer.h @@ -0,0 +1,39 @@ +#pragma once +#include +#include +#include +#include +#include "regsaccess.h" +#include "commondef.h" +#include "CorrectParam.h" + +class ICapturer +{ +public: + virtual ~ICapturer() {} + virtual void open() = 0; + virtual void open(HGScanConfig config,FPGAConfigParam fpgaparam) = 0; + virtual void close() = 0; + virtual void start() = 0; + virtual void stop() = 0; + virtual bool is_runing() = 0; + virtual void snap() = 0; + virtual void stopsnap() = 0; + virtual int getautosizeheight() = 0; + virtual void set_size(int width, int height) = 0; + virtual void* readFrame(int timeout) = 0; + + virtual void set_gain(int ix, int val) = 0; + virtual void set_offset(int ix, int val) = 0; + virtual void set_expo(int ix, int val) = 0; + + virtual std::shared_ptr regs() = 0; + virtual void reset() = 0; + virtual int width() = 0; + virtual int height() = 0; + virtual int color() = 0; + virtual void init_autocorrect(int colormode=0) = 0; + virtual void setcapturecall(std::function callback) = 0; + + +}; \ No newline at end of file diff --git a/device/gxx-linux/capimage/MonoCapturer.cpp b/device/gxx-linux/capimage/MonoCapturer.cpp new file mode 100644 index 0000000..d1bd23d --- /dev/null +++ b/device/gxx-linux/capimage/MonoCapturer.cpp @@ -0,0 +1,924 @@ +#include "MonoCapturer.h" +#include "config.h" +#include "applog.h" +#include "gvideoisp1.h" +#include "Gpio.h" +#include "DevUtil.h" +#include "FpgaComm.h" +#include "CorrectParam.h" +#include "correct_ultis.h" +#include "stringex.hpp" +#include "filetools.h" +#include "CImageMerge.h" +#include "commondef.h" +#include "hgutils.h" +#include "dailex.hpp" +#include "jsonconfig.h" +#include "ThreadPool.h" + +using namespace std; +using namespace cv; + +#define LOG_PATH "/usr/local/correct.log" +FileTools ft_log(LOG_PATH); + +static std::string loggername = "MonoCapturer"; +static double radio = 1.0; +static int offsetStep1[12]; +static int expStep1[2][3]; + +void initStep1() +{ + printf("initStep aaaaaaaaaaa \n"); + for (int i = 0; i < 2; i++) + { + for (int j = 0; j < 3; j++) + { + expStep1[i][j] = 600; + } + } + for (int i = 0; i < 12; i++) + { + offsetStep1[i] = 256; + printf("offsetStep[%d]=%d \n",i,offsetStep1[i]); + } +} + +MonoCapturer::MonoCapturer() : vdd_cis_3voff_pin(new GpioOut(CIS_3v3_Off)), + vdd_vis_5ven_pin(new GpioOut(CIS_5v_En)), + reset_pin(new GpioOut(50)), + image_in_transfer_pin(new Gpio(Image_In_Transfer)), + initDone_pin(new Gpio(Fpga_InitDone)), + fpgaLoad(new Gpio(70)), + fpga_conf_done(new Gpio(69)),//gpio init 导出 scanservice 仅操作IO + fpga_conf_initn(new Gpio(71)),//gpio init 导出 scanservice 仅操作IO + bcorrecting(false) +{ + LOG_INIT(); + fpga_conf_done->setDirection(Gpio::in); + fpgaComm.reset(new FpgaComm()); + fpga_reset(); + fpgaComm->resetADC(); + fpgaComm->setDelayTime(0X3e8); + // fpgaComm->update(); + video.reset(new VIDEO_CLASS()); + // GetFpgaparam(0x01,0); +} + +MonoCapturer::~MonoCapturer() +{ + if (video.get()) + video.reset(); + + printf("Exit ~MonoCapturer() \n"); +} + +void MonoCapturer::open() +{ +} + +void MonoCapturer::open(HGScanConfig config,FPGAConfigParam fpgaparam) +{ + fpgaComm->update(1); + // reset_pin->setValue(Gpio::Low); + // std::this_thread::sleep_for(std::chrono::milliseconds(50)); + // reset_pin->setValue(Gpio::High); + bool dunnancis = true; + int dpi; + if (dunnancis) + dpi = config.g200params.dpi == 0x02 ? 2 : (config.g200params.dpi == 0x03 ? 3 : 2); + else + dpi = config.g200params.dpi; + + int mode = config.g200params.color; + int channelwidth = dpi == 0x02 ? 1296 : (dpi == 0x03 ? 2592 : 864); + int channels = mode == 0x01 ? 3 : 1; + int width = channelwidth * channels; + auto phyHeight = paperHeight[(PaperSize)config.g200params.paper]; + int pixheight; // = ((int)((phyHeight / 25.4 * (dpi == 0x02 ? 300 : (dpi == 0x03 ? 600 : 200)) + 2) / 3)) * 3 * 2; + if (dunnancis) + { + int tdpi = config.g200params.dpi == 0x02 ? 300 : (config.g200params.dpi == 0x03 ? 600 : 200); + //int tdpi = config.g200params.dpi == 0x02 ? 285 : (config.g200params.dpi == 0x03 ? 570 : 190); + pixheight = ((int)((phyHeight / 25.4 * tdpi + 2) / 3)) * 3 * 2; + } + else + pixheight = ((int)((phyHeight / 25.4 * (config.g200params.dpi == 0x02 ? 300 : (config.g200params.dpi == 0x03 ? 600 : 200)) + 2) / 3) * 3) * 2; + + if (config.g200params.paper == (unsigned int)(PaperSize::G400_AUTO)||pixheight > 16380) // isp sup max height config 16383 + pixheight = 16380; + + int dstheight = pixheight; + + int fpgaheight = mode == 0x1 ? dstheight / 2 * 3 : dstheight / 2; //彩色配置fpga 高度要为目标图像高度的3倍 + //FPGAConfigParam fpgaparam = GetFpgaparam(config.g200params.dpi, mode);// == 0x02 ? 2 : (config.g200params.dpi == 0x03 ? 3 : 2) + // FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode); + printf("dpi = %d fpgaparam.sp=%d exp=%d gain=%d offset=%d LUT=%s \n", dpi, fpgaparam.Sp, fpgaparam.ExposureB[0], fpgaparam.GainB[0], fpgaparam.OffsetB[0], fpgaparam.LutPath.c_str()); + // int startsample= cistype.GetCisType()==CISVendor::DUNNAN_CIS_V0?205:262; +#ifdef G300 + int startsample = 202; + dpi = 0; + width = 1728; + if (papersMap.count((PaperSize)config.g200params.paper) > 0) + { + dstheight = papersMap[(PaperSize)config.g200params.paper].height; + } + else + { + dstheight = papersMap[PaperSize::G400_A4].height; //不区分G300 G400 + } + dstheight = config.g200params.color ? dstheight : dstheight /3; + if(config.g200params.dpi != 1) + dstheight = std::min(16002,dstheight*3/2); + fpgaheight = dstheight; +#else + int startsample = 208; + std::uint32_t m_fpgaversion = 0; + fpgaComm->read(15,m_fpgaversion); + if(Dail().GetValue().dails.in_voltage3 == 0) + startsample = 262; + else + startsample = m_fpgaversion == 0x90002? 205 : 208; +#endif + + float v_ratio = *((float*)(&fpgaparam.VRatio)); + fpgaparam.Sp /= v_ratio; + printf("\n apply sp = %d, v_ratio =%f",fpgaparam.Sp,v_ratio); + ModeFpga fpgamod = { + .colorMode = mode, + .dpi = dpi, + .led = 1, + .sample = startsample, // 256+39 + .adcA = 0, + .adcB = 0, + .selftest = 0, + .sp = fpgaparam.Sp}; // 600DPI 0x1450 300DPI 0xe10 + fpgaComm->setRegs(0x01, *((int *)(&fpgamod))); + fpgaComm->setSample(startsample); + fpgaComm->enableLed(true); + fpgaComm->setEnTestCol(false); + fpgaComm->setEnTestBit(false); + auto vsp_value = jsonconfig().getscannerinfo(); + if(vsp_value.clr_maxbright > 20 || vsp_value.clr_maxbright < 1) + vsp_value.clr_maxbright = 2; + if(vsp_value.gray_maxbright > 20 || vsp_value.gray_maxbright < 1) + vsp_value.gray_maxbright = 2; + fpgaComm->setVsp(vsp_value.clr_maxbright,vsp_value.gray_maxbright); + // fpgaComm->update(2); + configFPGAParam(mode, config.g200params.dpi); + // fpgaComm->update(3); + // fpgaComm->setFrameHeight(12); + // fpgaComm->capture(); + // auto data = video->read_frame(100); + // fpgaComm->enableLed(false); + video->open(width, dstheight); // 300dpi 7344/2 600dpi 7344 + printf("opened video with width = %d height = %d \n", width, dstheight); + fpgaComm->setFrameHeight(12); + for (int i = 0; i < 1; i++) + { + fpgaComm->capture(); // abort first frame + video->read_frame(100); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + printf("abort first frame \n"); + } + fpgaComm->setFrameHeight(fpgaheight); + printf("fpgaComm set height = %d \n", fpgaheight); + fpgaComm->update(3); + //initLut(fpgaparam.LutPath, config.g200params.color); + initLut(config.g200params.is_textcorrect?fpgaparam.LutPath:fpgaparam.TextLutPath,config.g200params.color); +} + +void MonoCapturer::close() +{ + if (video.get()) + video->close(); + //fpga_reload(); +} + +void MonoCapturer::Fpga_regsAccess_reset(bool enable){ + if(fpgaComm.get()) + fpgaComm->regsAccess_reset(enable); +} + +void MonoCapturer::start() +{ + if (video.get()) + video->start(); +} + +void MonoCapturer::MonoCapturer::stop() +{ + if (video.get()) + video->stop(); +} + +bool MonoCapturer::is_runing() +{ + return false; +} + +void MonoCapturer::snap() +{ + fpgaComm->capture(); +} + +void MonoCapturer::stopsnap() +{ +} + +int MonoCapturer::getautosizeheight() +{ + unsigned int val; + unsigned int reg8 = 0; + + fpgaComm->read(8, reg8); + // std::cout << "1 reg[8]:" << string_format("0x%08x", reg8) << std::endl; + // fpgaComm->update(4); + fpgaComm->read(14, val); + int regv = val; + val &= 0x0000ffff; + // std::cout << string_format("ONE height = %d reg[14] = %d \n", val, regv); + // fpgaComm->update(5); + fpgaComm->write(8, reg8 & 0xfffffff7); + // std::cout << string_format("ONE reg[8] = %d \n", reg8 & 0xfffffff7); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + // fpgaComm->update(6); + fpgaComm->read(14, val); + regv = val; + val &= 0x0000ffff; + fpgaComm->read(8, reg8); + // std::cout << "2 reg[8]:" << string_format("0x%08x", reg8) << std::endl; + std::cout << string_format("TWO height = %d reg[14] = %d \n", val, regv); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + fpgaComm->write(8, reg8 | 0x8); + // fpgaComm->write(8,0x02260008); + // fpgaComm->update(7); + // fpgaComm->read(8, reg8); + // std::cout << "2 reg[8]:" << string_format("0x%08x", reg8) << std::endl; + return val; + + // return fpgaComm->getFrameHeight(); +} +void MonoCapturer::set_size(int width, int height) +{ + if (video.get()) + video->set_size(width, height); +} + +void MonoCapturer::set_sp(int sp) +{ + fpgaComm->setSp(sp); +} + +void *MonoCapturer::readFrame(int timeout) +{ + return video->read_frame(timeout); +} + +void MonoCapturer::set_gain(int ix, int val) +{ + for (int i = 0; i < 6; i++) + { + if (ix) + fpgaComm->setAGain(i, val); + else + fpgaComm->setBGain(i, val); + } +} + +void MonoCapturer::set_offset(int ix, int val) +{ + for (int i = 0; i < 6; i++) + { + if (ix) + fpgaComm->setAOffset(i, val); + else + fpgaComm->setBOffset(i, val); + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +} + +void MonoCapturer::set_expo(int ix, int val) +{ + switch (ix) + { + case 0: + fpgaComm->setAExposureR(val); + break; + case 1: + fpgaComm->setAExposureG(val); + break; + case 2: + fpgaComm->setAExposureB(val); + break; + case 3: + fpgaComm->setBExposureR(val); + break; + case 4: + fpgaComm->setBExposureG(val); + break; + case 5: + fpgaComm->setBExposureB(val); + break; + default: + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); +} + +std::shared_ptr MonoCapturer::regs() +{ + return fpgaComm; +} + +void MonoCapturer::reset() +{ + fpga_reset(); + // fpgaComm->resetADC(); + // fpgaComm->setDelayTime(0X3e8); + // fpgaComm->setRegs(0x00, fpgaComm->getRegs(0x00)); + // fpgaComm->setRegs(0x01, fpgaComm->getRegs(0x01)); +} + +int MonoCapturer::width() +{ +#ifdef G300 + return 1728; +#else + int dpi = fpgaComm->getDpi(); + int channel = 1; + int width = dpi == 0x02 ? 1296 * channel : (dpi == 0x03 ? (2592 * channel) : (864 * channel)); + // printf("get width = %d \n", width); + return width; +#endif +} + +int MonoCapturer::height() +{ + return fpgaComm->getFrameHeight(); +} + +int MonoCapturer::color() +{ + return fpgaComm->getColorMode() ? 16 : 0; +} + +void MonoCapturer::init_autocorrect(int colormode) +{ + std::thread t_correctthread = std::thread(&MonoCapturer::correctcolor, this); + t_correctthread.detach(); +} + +void MonoCapturer::configFPGAParam(int mode, int dpi) +{ + printf("dpi = %d mode = %d \n", dpi, mode); + //fpgaComm->resetADC(); + FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode); + // int offF[6]={0,0,0,0,0,200}; + // int offB[6]={0,0,0,0,0,0}; + for (int i = 0; i < 6; i++) + { + if (i < 3) + { + set_expo(i, fpgaparam.ExposureF[i]); + printf("fpgaparam.ExposureF[%d] = %d \n", i, fpgaparam.ExposureF[i]); + } + else + { + set_expo(i, fpgaparam.ExposureB[i % 3]); + printf("fpgaparam.ExposureB[%d] = %d \n", i, fpgaparam.ExposureB[i % 3]); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + fpgaComm->setAOffset(i, fpgaparam.OffsetF[i]); + // fpgaComm->setAOffset(i,offF[i]); + printf("fpgaparam.setAOffset[%d] = %d \n", i, fpgaparam.OffsetF[i]); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + fpgaComm->setBOffset(i, fpgaparam.OffsetB[i]); + // fpgaComm->setBOffset(i, offB[i]); + printf("fpgaparam.OffsetB[%d] = %d \n", i, fpgaparam.OffsetB[i]); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + fpgaComm->setAGain(i, fpgaparam.GainF[i]); + printf("fpgaparam.GainF[%d] = %d \n", i, fpgaparam.GainF[i]); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + fpgaComm->setBGain(i, fpgaparam.GainB[i]); + printf("fpgaparam.GainB[%d] = %d \n", i, fpgaparam.GainB[i]); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + } +} + +void MonoCapturer::openDevice(int dpi, int mode) +{ + // reset_pin->setValue(Gpio::Low); + // std::this_thread::sleep_for(std::chrono::milliseconds(50)); + // reset_pin->setValue(Gpio::High); + int config_dpi = dpi == 1 ? 2 : dpi; + int channelwidth = config_dpi == 0x02 ? 1296 : (config_dpi == 0x03 ? 2592 : 864); + int channels = mode == 0x01 ? 3 : 1; + int width = channelwidth * channels; + int dstheight = 200; + int fpgaheight = mode == 0x1 ? dstheight / 2 * 3 : dstheight; //彩色配置fpga 高度要为目标图像高度的3倍 + + FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode); +#ifdef G300 + int startsample = 202; + config_dpi = 0; + width = 1728; + dstheight = mode ? 6000 : 2000; + fpgaheight = dstheight; +#else + int startsample = 208; + std::uint32_t m_fpgaversion = 0; + fpgaComm->read(15,m_fpgaversion); + if(Dail().GetValue().dails.in_voltage3 == 0) + startsample = 262; + else + startsample = m_fpgaversion == 0x90002? 205 : 208; +#endif + printf("fpgaparam.sp=%d exp=%d gain=%d offset=%d LUT=%s", fpgaparam.Sp, fpgaparam.ExposureB[0], fpgaparam.GainB[0], fpgaparam.OffsetB[0], fpgaparam.LutPath.c_str()); + // int startsample= cistype.GetCisType()==CISVendor::DUNNAN_CIS_V0?205:262; + float v_ratio = *((float*)(&fpgaparam.VRatio)); + fpgaparam.Sp *= v_ratio; + printf("\n openDevice apply sp = %d, v_ratio =%f",fpgaparam.Sp,v_ratio); + ModeFpga fpgamod = { + .colorMode = mode, + .dpi = config_dpi, + .led = 1, + .sample = startsample, // 256+39 + .adcA = 0, + .adcB = 0, + .selftest = 0, + .sp = fpgaparam.Sp}; // 600DPI 0x1450 300DPI 0xe10 + fpgaComm->setRegs(0x01, *((int *)(&fpgamod))); + fpgaComm->setSample(startsample); + fpgaComm->enableLed(true); + fpgaComm->setEnTestCol(false); + fpgaComm->setEnTestBit(false); + auto vsp_value = jsonconfig().getscannerinfo(); + if(vsp_value.clr_maxbright > 20 || vsp_value.clr_maxbright < 1) + vsp_value.clr_maxbright = 2; + if(vsp_value.gray_maxbright > 20 || vsp_value.gray_maxbright < 1) + vsp_value.gray_maxbright = 2; + fpgaComm->setVsp(vsp_value.clr_maxbright,vsp_value.gray_maxbright); + configFPGAParam(mode, dpi); + + video->open(width, dstheight); // 300dpi 7344/2 600dpi 7344 + printf("opened video with width = %d height = %d \n", width, dstheight); + fpgaComm->setFrameHeight(12); + for (int i = 0; i < 1; i++) + { + fpgaComm->capture(); // abort first frame + video->read_frame(100); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + printf("abort first frame \n"); + } + fpgaComm->setFrameHeight(fpgaheight); +} + +void MonoCapturer::creatcorrectconfig(int dpi, int mode) +{ + printf(" opendevice"); + openDevice(dpi, mode); + printf(" opendevice end "); + bool isDone = false; + int i = 1; + initStep1(); + while (!isDone) //先暗场 + { + string log = "==============================第" + to_string(i) + "次==============================="; + ft_log.append_log(log); + configFPGAParam(mode, dpi); + ft_log.append_log(log); + fpgaComm->enableLed(false); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + fpgaComm->capture(); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + isDone = saveLutImg(dpi, mode, true); // 0 color_black 1 color_white 2 gray_balck 3 gray_white + i++; + } + i = 1; + isDone = false; + initStep1(); + while (!isDone) //后明场 + { + configFPGAParam(mode, dpi); + string log = "==============================第" + to_string(i) + "次==============================="; + ft_log.append_log(log); + fpgaComm->enableLed(true); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + fpgaComm->capture(); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + isDone = saveLutImg(dpi, mode, false); + i++; + } + printf("creatcorrectconfig %s \n", (mode == IMAGE_COLOR ? " Color" : " Gray")); + //creatLUTData(dpi, mode); + video->close(); +} + +static int savelutindex = 0; +bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) +{ + int config_dpi = dpi == 1 ? 2 : dpi; +#ifdef G300 + int offset_indexs[] = {3, 4, 5, 2, 1, 0, 0, 1, 2, 5, 4, 3}; +#else + int offset_indexs[] = {0, 1, 2, 5, 4, 3, 3, 4, 5, 2, 1, 0}; +#endif + int channels = mode == IMAGE_COLOR ? 3 : 1; + int height = 100; + int width = config_dpi == 0x02 ? 1296 : (config_dpi == 0x03 ? 2592 : 864); + int orgimgwidth = width * 2 * 3 * channels; + int dstwidth = width * 2 * 3; +#ifdef G300 + orgimgwidth = 1728 * channels * 3; + height = 6000 / 9 *3 ; +#endif + bool isNeedSave = true; + string log; + void *data = video->read_frame(10000); + if (data == NULL) + { + isNeedSave = false; + log = "WARNNING WARNNING WARNNING FAILDED TO READ IMAGE DATA !!!!!!!!!!!!!!!!!!!\r\n"; + ft_log.append_log(log); + if (m_captureCallback) + m_captureCallback(mode, log); + return isNeedSave; + } + cv::Mat src(height, orgimgwidth, CV_8UC1, data); + //cv::imwrite(std::to_string(savelutindex++) + ".jpg", src); +#ifdef G300 + cv::Mat mrgmat = GetStitchMat(mode ==1?1:0,orgimgwidth,height,src); +#else + CImageMerge t_marge; + cv::Mat mrgmat = t_marge.MergeImage(mode == 0x01, src, dstwidth, height,0x90001); +#endif + mrgmat = mrgmat(cv::Rect(0,20,mrgmat.cols,mrgmat.rows-20)); + // return false; + FPGAConfigParam param = GetFpgaparam(dpi, mode); + + if (black) //暗场 + { + double offValues[12]; + std::vector bflags; + for (volatile int n = 0; n < 2; n++) + { + cv::Mat img = mrgmat(cv::Rect(mrgmat.cols * n / 2, 10, mrgmat.cols / 2, mrgmat.rows - 10)).clone(); + int offset_total = 0; + for (volatile int s = 0; s < 6; s++) // + { + int k = n * 6 + s; + int offset_wdth; + if ((k == 5) || (k == 6)) + { + offset_wdth = config_dpi == 0x03 ? 864 : (config_dpi == 0x02 ? 432 : 288); + } + else + { + offset_wdth = config_dpi == 0x03 ? 1296 : (config_dpi == 0x02 ? 648 : 432); + } +#ifdef G300 + offset_wdth =432; +#endif + double min,max; + //auto t_mat= img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10)); + //cv::minMaxLoc(t_mat,&min,&max); + cv::Scalar mean = cv::mean(img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10))); + //printf("AAAAAAAAAAAAAAAAAAAAAAAAAAA min = %.2f max= %.2f mean = %0.2f \n",min,max); + offset_total += offset_wdth; + offValues[k] = mean.val[0]; + printf("\noffValues[%d] = %f",k,mean.val[0]); + bflags.push_back(false); + //offValues[k] = min; + } + } + + // std::string clrmode = (mode == 0x01 ? "彩色" : " 灰度"); + // log = "开始" + clrmode + "暗场校正 \n"; + for (volatile int s = 0; s < 2; s++) + { + int offsets[6]; // = (int *)(s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]); + memcpy(offsets, (s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]), sizeof(param.OffsetF)); + for (volatile int j = 0; j < 6; j++) + { + int k = s * 6 + j; + double diff = BLACK_DIFF(offValues[k]); + //double diff = 3-offValues[k]; + double step = radio * diff; + int preStep = offsetStep1[k]; + printf("offsetStep1[%d]=%d \n",k,offsetStep1[k]); + if (step * preStep < 0) + { + step = 0 - preStep / 2; + } + else + { + radio = 1; + } + + if (step < 1 && step > 0) + step = 1; + if (step < 0 && step > -1) + step = -1; + + + // FMT_STEP(step); + bool isMinStep = abs(step) == 1 && step == offsetStep1[k]; + bool isOutBounds = offsets[j] >= 255 && step > 0; + isOutBounds |= offsets[j] <= 0 && step < 0; + log += " 暗场校正 :" + std::to_string(k) + ";diff:" + std::to_string(diff) + ";light:" + std::to_string(offValues[k]) + ";offset:" + std::to_string(offsets[j]) + ";step:" + std::to_string(step) + "\r\n"; + if (isOutBounds) + log += " 第" + std::to_string(k) + "条带暗场校正异常,暗场值无法降低 \r\n"; + else if (abs(step) > 1 || isMinStep) + { + offsetStep1[k] = (int)(step); + offsets[offset_indexs[k]] += step; + log += "offsetStep1" + std::to_string(k) + " = " + std::to_string(offsetStep1[k]) + ", offset_indexs" + std::to_string(k) + " =" + std::to_string(offset_indexs[k]) + "\r\n"; + + if (offsets[offset_indexs[k]] < 1) + offsets[offset_indexs[k]] = 1; + if (offsets[offset_indexs[k]] > 255) + offsets[offset_indexs[k]] = 255; + //isNeedSave = false; + bflags[k] = false; + } + else + { + bflags[k] = true; + printf("channel[%d] black correct done\n",k); + } + + + log += (s == 0 ? "彩色正面" : "彩色背面"); + log += "偏移值:" + std::to_string(offsets[0]) + "," + std::to_string(offsets[1]) + "," + std::to_string(offsets[2]) + "," + std::to_string(offsets[3]) + "," + std::to_string(offsets[4]) + "," + std::to_string(offsets[5]) + "\r\n"; + // log += (s == 0 ? "彩色正面暗场校正完成 \r\n" : "彩色背面暗场校正完成 \r\n"); + ft_log.append_log(log); + if (m_captureCallback) + m_captureCallback(mode, log); + log = ""; + } + auto siez = sizeof(param.OffsetF); + memcpy((s == 0 ? ¶m.OffsetF[0] : ¶m.OffsetB[0]), offsets, sizeof(param.OffsetF)); + } + + for(int i = 0;i 30) + radio = 2; + else + radio = 1; + double step = diff * radio; + int preStep = *((int *)expStep + k); + if (step * preStep < 0) + { + step = 0 - preStep / 2; + } + if (step < 1 && step > 0) + step = 1; + if (step < 0 && step > -1) + step = -1; + + bool isMinStep = abs(step) == 1 && step == *((int *)expStep + k); + bool isOutBounds = exposures[x] >= (param.Sp -5) && step > 0; + isOutBounds |= exposures[x] <= 0 && step < 0; + if (isOutBounds) + log += " 第" + to_string(x) + "个明场校正异常 \r\n"; + else if (abs(diff) >= 1 || isMinStep) + { + *((int *)expStep + k) = (int)(step); + exposures[x] += step; + if (exposures[x] > (param.Sp -5)) + { + exposures[x] = (param.Sp -5); + } + if (exposures[x] < 0) + exposures[x] = 0; + isNeedSave = false; + } + log += " 曝光值:" + to_string(exposures[x]) + "\r\n"; + log += " 调整步长:" + to_string(*((int *)expStep + k)) + "\r\n"; + } + memcpy((s == 0 ? ¶m.ExposureF[0] : ¶m.ExposureB[0]), exposures, sizeof(param.ExposureB)); + } + ft_log.append_log(log); + if (m_captureCallback) + m_captureCallback(mode, log); + + if (isNeedSave) + { + log = "彩色明场校正完成\r\n"; + if (m_captureCallback) + m_captureCallback(mode, log); + // log =""; + imwrite(param.Flat_WhitePath, mrgmat); + } + } + else + { + double values[2]; + values[0] = cv::mean(mrgmat(cv::Rect(0, 0, mrgmat.cols / 2, mrgmat.rows))).val[0]; + values[1] = cv::mean(mrgmat(cv::Rect(mrgmat.cols / 2, 0, mrgmat.cols / 2, mrgmat.rows))).val[0]; + log = "-----开始灰色明场校正-----\r\n"; + log += " 灰色扫描灰度明场均值:" + to_string(values[0]) + "," + to_string(values[1]) + "\r\n"; + if (m_captureCallback) + m_captureCallback(mode, log); + for (int s = 0; s < 2; s++) + { + int *exposures = (int *)(s == 0 ? param.ExposureF : param.ExposureB); + int diff = LIGHT_DIFF(param.MaxBright, values[s]); + if(abs(diff) > 30) + radio = 2; + else + radio = 1; + double step = diff * radio; + log += " 明场:" + to_string(s) + ";diff:" + to_string(diff) + "\r\n"; + int preStep = expStep[s][0]; + if (step * preStep < 0) + { + step = 0 - preStep / 2; + } + else + { + radio = 1; + } + if (step < 1 && step > 0) + step = 1; + if (step < 0 && step > -1) + step = -1; + + int exp = *(exposures + 1); + // std::string ss1(string_format("exp[%d] = %d step = %.3f \r\n", s, exp, step)); + // log += ss1; + bool isMinStep = abs(step) == 1 && step == expStep[s][0]; + bool isOutBounds = exp >= (param.Sp -5) && step > 0; + isOutBounds |= exp <= 0 && step < 0; + if (isOutBounds) + log += " 第" + to_string(s) + "个明场校正异常 \r\n"; + else if (abs(diff) > 1 || isMinStep) + { + exp += step; + if (exp < 0) + exp = 0; + if (exp >(param.Sp -5)) + exp = (param.Sp -5); + + float coffe[3] = {1, 1, 1}; // 0.2, 1,0.51 + for (int k = 0; k < 3; k++) + { + *(exposures + k) = (int)(exp * coffe[k]); + expStep[s][k] = (int)(step); + std::string exps(string_format("expStep[%d][%d] = %.3f\r\n", s, k, step)); + log += exps; + std::string ss(string_format("exposures[%d] = %0.3f \r\n", k, exposures[k])); + log += ss; + } + isNeedSave = false; + } + } + ft_log.append_log(log); + if (m_captureCallback) + m_captureCallback(mode, log); + if (isNeedSave) + { + printf("Save LUT image path :%s \n", param.Flat_WhitePath.c_str()); + log = "灰度明场校正完成\r\n"; + if (m_captureCallback) + m_captureCallback(mode, log); + log = ""; + imwrite(param.Flat_WhitePath, mrgmat); + } + } + } + SaveFpgaparam(param); + printf("exit Save_lut \n"); + return isNeedSave; +} + +void MonoCapturer::correctcolor() +{ + printf(" correctcolor start \n"); + auto _start = std::chrono::steady_clock::now(); + ThreadPool pool(2); + std::queue> fu_correct; + std::string loginfo = "Start Correctcolor 200DPI COLOR \r\n"; + // if (m_captureCallback) + // m_captureCallback(0x01, loginfo); + creatcorrectconfig(0x01, IMAGE_COLOR); + auto param = GetFpgaparam(0x01,IMAGE_COLOR); + fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x01,IMAGE_COLOR,param);})); + loginfo = "-----------200DPI COLOR Correct Done----------- \r\n\r\n Start Correctcolor 200DPI GRAY \r\n"; + if (m_captureCallback) + m_captureCallback(0x01, loginfo); + creatcorrectconfig(0x01, IMAGE_GRAY); + param = GetFpgaparam(0x01,IMAGE_GRAY); + fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x01,IMAGE_GRAY,param);})); + loginfo = "-----------200DPI Gray Correct Done----------- \r\n\r\n Start Correctcolor 200DPI COLOR \r\n"; + if (m_captureCallback) + m_captureCallback(0x02, loginfo); + + creatcorrectconfig(0x02, IMAGE_COLOR); + param = GetFpgaparam(0x02,IMAGE_COLOR); + fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x02,IMAGE_COLOR,param);})); + loginfo = "-----------300DPI COLOR Correct Done----------- \r\n\r\n Start Correctcolor 300DPI GRAY \r\n"; + if (m_captureCallback) + m_captureCallback(0x02, loginfo); + creatcorrectconfig(0x02, IMAGE_GRAY); + param = GetFpgaparam(0x02,IMAGE_GRAY); + fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x02,IMAGE_GRAY,param);})); + loginfo = "-----------300DPI Gray Correct Done----------- \r\n\r\n Start Correctcolor 600DPI COLOR \r\n"; +#ifndef G300 + if (m_captureCallback) + m_captureCallback(0x03, loginfo); + creatcorrectconfig(0x03, IMAGE_COLOR); + param = GetFpgaparam(0x03,IMAGE_COLOR); + fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x03,IMAGE_COLOR,param);})); + loginfo = "-----------600DPI COLOR Correct Done----------- \r\n\r\n Start Correctcolor 600DPI GRAY \r\n"; + if (m_captureCallback) + m_captureCallback(0x03, loginfo); + creatcorrectconfig(0x03, IMAGE_GRAY); + param = GetFpgaparam(0x03,IMAGE_GRAY); + fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x03,IMAGE_GRAY,param);})); + loginfo = "-----------600DPI Gray Correct Done----------- \r\n\r\n "; + if (m_captureCallback) + m_captureCallback(0x03, loginfo); +#endif + while(fu_correct.size()) + { + fu_correct.front().get(); + fu_correct.pop(); + } + loginfo = "******Correct Done****** time " + std::to_string(std::chrono::duration(std::chrono::steady_clock::now() - _start).count())+"s"; + if (m_captureCallback) + m_captureCallback(0x03, loginfo); +} + +void MonoCapturer::fpga_reset() +{ + reset_pin->setValue(Gpio::Low); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + reset_pin->setValue(Gpio::High); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); +} + +void MonoCapturer::fpga_reload() +{ + // fpga 代码重载 + fpgaLoad->setValue(Gpio::Low); + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + fpga_conf_initn->setValue(Gpio::Low); + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + printf("\n fpga_conf_done value %d",fpga_conf_done->getValue()); + fpgaLoad->setValue(Gpio::High); + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + fpga_conf_initn->setValue(Gpio::High); + //std::this_thread::sleep_for(std::chrono::milliseconds(5)); + printf("\n fpga_conf_done value %d",fpga_conf_done->getValue()); + // while(fpga_conf_done->getValue() == Gpio::GpioLevel::Low) + // std::this_thread::sleep_for(std::chrono::milliseconds(5)); + std::this_thread::sleep_for(std::chrono::seconds(3)); + printf("\n fpga_conf_done value %d",fpga_conf_done->getValue()); + fpgaComm->resetADC(); + fpgaComm->update(0); +} \ No newline at end of file diff --git a/device/gxx-linux/capimage/MonoCapturer.h b/device/gxx-linux/capimage/MonoCapturer.h new file mode 100644 index 0000000..136c76d --- /dev/null +++ b/device/gxx-linux/capimage/MonoCapturer.h @@ -0,0 +1,67 @@ +#pragma once +#include "ICapturer.h" + +class FpgaComm; +class gVideo; +class Gpio; + +class MonoCapturer : public ICapturer +{ +private: + /* data */ +public: + MonoCapturer(/* args */); + virtual ~MonoCapturer(); + virtual void open(); + virtual void open(HGScanConfig config,FPGAConfigParam fpgaparam); + virtual void close(); + virtual void start(); + virtual void stop(); + virtual bool is_runing(); + virtual void snap(); + virtual void stopsnap(); + virtual int getautosizeheight(); + virtual void set_size(int width, int height); + virtual void set_sp(int sp); + + virtual void *readFrame(int timeout); + + virtual void set_gain(int ix, int val); + virtual void set_offset(int ix, int val); + virtual void set_expo(int ix, int val); + + virtual std::shared_ptr regs(); + virtual void reset(); + virtual int width(); + virtual int height(); + virtual int color(); + virtual void init_autocorrect(int colormode); + virtual void setcapturecall(std::function callback) + { + m_captureCallback = callback; + }; + virtual void Fpga_regsAccess_reset(bool enable); +private: + void configFPGAParam(int mode, int dpi); + void openDevice(int dpi, int mode); + void creatcorrectconfig(int dpi, int mode); + bool saveLutImg(int dpi, int mode, bool black); + void correctcolor(); + void fpga_reset(); + void fpga_reload(); + +private: + std::function m_captureCallback; + std::shared_ptr video; + std::shared_ptr vdd_cis_3voff_pin; + std::shared_ptr vdd_vis_5ven_pin; + std::shared_ptr reset_pin; + std::shared_ptr image_in_transfer_pin; + std::shared_ptr initDone_pin; + std::shared_ptr fpgaLoad; + std::shared_ptr fpgaComm; + std::shared_ptr fpga_conf_initn; + std::shared_ptr fpga_conf_done; + bool bcorrecting; + std::thread m_correctthread; +}; diff --git a/device/gxx-linux/capimage/SysInforTool.cpp b/device/gxx-linux/capimage/SysInforTool.cpp new file mode 100644 index 0000000..68219bd --- /dev/null +++ b/device/gxx-linux/capimage/SysInforTool.cpp @@ -0,0 +1,183 @@ +#pragma once +#include "SysInforTool.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int errno; +static void get_system_output(char *cmd, char *output, int size) +{ + FILE *fp = NULL; + fp = popen(cmd, "r"); + if (fp) + { + if (fgets(output, size, fp) != NULL) + { + if (output[strlen(output) - 1] == '\n') + output[strlen(output) - 1] = '\0'; + } + pclose(fp); + } +} + +/*block to kbyte*/ +static unsigned long kscale(unsigned long m_block, unsigned long m_kbyte) +{ + + return ((unsigned long long) m_block * m_kbyte + 1024 / 2 ) /1024; +} + +/*convert size to GB MB KB*/ +static void convert_size(float m_size, int *dest) +{ + if((((m_size / 1024.0) / 1024.0)) >= 1.0) + { + *dest = (int)((m_size/1024.0)/1024.0); + } + else if((m_size / 1024.0) >= 1.0) + { + *dest = (int)(m_size/1024); + } +} + + +SysInforTool::SysInforTool(ScannerSysInfo tinfo) +{ + m_sysinfo = tinfo; +} + +SysInforTool::~SysInforTool() +{ + +} + +/*获取文件系统信息*/ +int SysInforTool::get_fileSystem_info(const char *fileSystem_name,struct fileSystem_info *fi) +{ + struct statfs buf; + float fileSystem_total_size = 0; + float fileSystem_free_size = 0; + + if(statfs(fileSystem_name,&buf)) + { + fprintf(stderr,"statfs %s\n",strerror(errno)); + return -1; + } + + switch(buf.f_type) + { + case 0xEF51: + case 0xEF53: + sprintf(fi->fileSystem_format,"EXT"); + break; + + case 0x4d44: + sprintf(fi->fileSystem_format,"FAT"); + break; + + case 0x5346544e: + sprintf(fi->fileSystem_format,"NIFS"); + break; + + default: + sprintf(fi->fileSystem_format,"unknown"); + break; + } + + //bzero(&fi->fileSystem_total_capacity,sizeof(fi->fileSystem_total_capacity)); + //bzero(&fi->fileSystem_free_capacity,sizeof(fi->fileSystem_free_capacity)); + + printf("blocks %ld\n",buf.f_blocks); + printf("bfree %ld\n",buf.f_bfree); + printf("bsize %ld\n",buf.f_bsize); + + fileSystem_total_size = + (float)(kscale(buf.f_blocks, buf.f_bsize)); + fileSystem_free_size = + (float)(kscale(buf.f_bfree, buf.f_bsize)); + + printf("total %f\n",fileSystem_total_size); + printf("free %f\n",fileSystem_free_size); + + fi->fileSystem_total_capacity = fileSystem_total_size; + fi->fileSystem_free_capacity = fileSystem_free_size; + //convert_size(fileSystem_total_size,(int*)(&fi->fileSystem_total_capacity)); + //convert_size(fileSystem_free_size,(int*)(&fi->fileSystem_free_capacity)); + + bzero(fi->fileSystem_permissions,sizeof(fi->fileSystem_permissions)); + sprintf(fi->fileSystem_permissions,"rw"); + + return 0; +} + +std::string SysInforTool::GetSysInfo() +{ + struct sysinfo memInfo; + sysinfo(&memInfo); + m_sysinfo.MemTotal = memInfo.totalram; + fileSystem_info fileinfo; + get_fileSystem_info("/",&fileinfo); + m_sysinfo.DiskTotal = fileinfo.fileSystem_total_capacity;//KB + m_sysinfo.DiskUsed = fileinfo.fileSystem_free_capacity;//KB + + struct utsname t_uname; + if(uname(&t_uname)!=0) + perror("uname doesn't return 0, so there is an error"); + + printf("System Name = %s\n", t_uname.sysname); + printf("Node Name = %s\n", t_uname.nodename); + printf("Version = %s\n", t_uname.version); + printf("Release = %s\n", t_uname.release); + printf("Machine = %s\n", t_uname.machine); + if(strcmp(t_uname.nodename,"linaro-alip")==0 && strcmp(t_uname.machine,"armv7l")==0) + { + m_sysinfo.Systype=SysType::Sys_Linux_Debian; + m_sysinfo.CPU = SCPU::CPU_3288; + printf("Machine = %s CPU = %s \n", "Sys_Linux_Debian","CPU_3288"); + } + else if(strcmp(t_uname.nodename,"linaro-alip")==0 && strcmp(t_uname.machine,"aarch64")==0) + { + m_sysinfo.Systype = SysType::Sys_Linux_Debian; + m_sysinfo.CPU = SCPU::CPU_3399; + printf("Machine = %s CPU = %s \n", "Sys_Linux_Debian","CPU_3399"); + } + m_sysinfo.MtType = SMBType::MB_DRV_8825; + m_sysinfo.Cistype = HGCISType::CIS_DUNNAN_MONO_V0; + char output[512]; + get_system_output("uname -a",output,sizeof(output)); + std::string ver(output); + m_sysinfo.KernelVersion = ver; + printf("system version = %s \n",ver.c_str()); + json j; + struct2json(j,m_sysinfo); + std::ofstream o("/usr/local/huago/sysinfo.json"); + o << std::setw(4) << j << std::endl; + return j.dump(); +} + +void SysInforTool::struct2json(json& j,ScannerSysInfo& info) +{ + j["CPU"]=info.CPU; + j["Systype"]=info.Systype; + j["Screentype"] = info.Screentype; + j["MtBoardVersion"] = info.MtBoardVersion; + j["MtType"] = info.MtType; + j["FPGAVersion"] = info.FPGAVersion; + j["Cistype"] = info.Cistype; + j["MaxRes"] = info.ResSup; + j["MemTotal"] = info.MemTotal; + j["DiskTotal"] = info.DiskTotal; + j["DiskUsed"] = info.DiskUsed; + j["KernelVersion"] = info.KernelVersion; + j["Have_EthernPort"] = info.Have_EthernPort; + j["ServiceVersion"] = info.ServiceVersion; + j["UsbProtocol"] = info.UsbProtocol; +} \ No newline at end of file diff --git a/device/gxx-linux/capimage/SysInforTool.h b/device/gxx-linux/capimage/SysInforTool.h new file mode 100644 index 0000000..ac924ba --- /dev/null +++ b/device/gxx-linux/capimage/SysInforTool.h @@ -0,0 +1,26 @@ +#pragma once +#include "scannersysinfo.h" +#include "json.hpp" + +using json=nlohmann::json; + +struct fileSystem_info{ + char fileSystem_format[8]; + unsigned int fileSystem_total_capacity; + unsigned int fileSystem_free_capacity; + char fileSystem_permissions[3]; +}; + + +class SysInforTool +{ +public: + SysInforTool(ScannerSysInfo tinfo); + ~SysInforTool(); + std::string GetSysInfo(); +private: + int get_fileSystem_info(const char *fileSystem_name,struct fileSystem_info *fi); + void struct2json(json& j,ScannerSysInfo& info); +private: + ScannerSysInfo m_sysinfo; +}; diff --git a/device/gxx-linux/capimage/correct_ultis.cpp b/device/gxx-linux/capimage/correct_ultis.cpp new file mode 100644 index 0000000..1774ccd --- /dev/null +++ b/device/gxx-linux/capimage/correct_ultis.cpp @@ -0,0 +1,427 @@ +#include +#include +#include +#include +#include "correct_ultis.h" +#include "CorrectParam.h" +#include "commondef.h" +#define USE_NEWFLAT +using namespace cv; + +void initStep() +{ + for (int i = 0; i < 2; i++) + { + for (int j = 0; j < 3; j++) + { + expStep[i][j] = 600; + } + } + for (int i = 0; i < 12; i++) + { + offsetStep[i] = 256; + printf("offsetStep[%d]=%d \n",i,offsetStep[i]); + } + +} + + +cv::Mat extractRepresentRow2(const cv::Mat &src) +{ + cv::Mat BWbalenceSrc(1, src.cols * src.channels(), CV_8UC1); + + cv::Mat temp_imageBW(src.rows, src.cols * src.channels(), CV_8UC1, src.data); + + for (size_t i = 0; i < BWbalenceSrc.cols; i++) + BWbalenceSrc.at(0, i) = cv::mean(temp_imageBW(cv::Rect(i, 0, 1, temp_imageBW.rows)))[0]; + + return BWbalenceSrc; +} +#ifdef G300 +#define CHANNEL 432 +#else +#define CHANNEL 408 +#endif +cv::Mat loadLUT(const std::string& file) +{ + cv::Mat dataFile = cv::imread(file, cv::IMREAD_ANYCOLOR); + + long total = dataFile.total(); + int step = total / 256; + + int channel = 1; + #ifndef USE_NEWFLAT + if (step == 4896 || step == 7344 ) + channel = 408; + else if (step == 14688 ||step== 22032 || step == 44064) + channel = 432; //486 + #else + channel = CHANNEL; + #endif + cv::Mat lut(step / channel, 256, CV_8UC(channel)); + memcpy(lut.data, dataFile.data, total); + return lut; +} + +void initLut(const std::string lutpath,bool iscolor) +{ + printf("\n-----------------------------"); + lutColorMat.release(); + lutGrayMat.release(); + if (!lutpath.empty() && (access(lutpath.c_str(), F_OK) == 0)) + { + printf("\n %s",lutpath.c_str()); + if(iscolor) + lutColorMat = loadLUT(lutpath); //彩色校正值 + else + lutGrayMat = loadLUT(lutpath); //灰色校正值 + } +} + + +void correctColor(cv::Mat& src, int dpi, int mode,bool isText) +{ + Mat lutMat; + FPGAConfigParam param = GetFpgaparam(dpi, mode); + std::string path = isText?param.TextLutPath : param.LutPath; + printf("\n %s",path.c_str()); + if (src.type() == CV_8UC3) + { + if (lutColorMat.empty()) + { + if (access(path.c_str(), F_OK) != -1) + { + lutColorMat = loadLUT(path); + } + else + { + printf("error error error %s NOT FOUND \n",path.c_str()); + return; + } + } + lutMat = lutColorMat; + } + else + { + if (lutGrayMat.empty()) + { + if (access(path.c_str(), F_OK) != -1) + { + lutGrayMat = loadLUT(path); + } + else + { + printf("error error error %s NOT FOUND", path.c_str()); + return; + } + } + lutMat = lutGrayMat; + } + if (lutMat.empty()) + { + return; + } + + cv::Mat image_temp(src.rows, src.cols * src.channels() / lutMat.channels(), CV_8UC(lutMat.channels()), src.data); + + for (size_t i = 0; i < image_temp.cols; i++) + cv::LUT(image_temp(cv::Rect(i, 0, 1, image_temp.rows)), lutMat(cv::Rect(0, i, 256, 1)), image_temp(cv::Rect(i, 0, 1, image_temp.rows))); +} + + +void creatLUTData(int dpi , int mode,FPGAConfigParam param) +{ + printf("eneter creatLUTData \n"); + auto colormode = mode == 1 ? IMREAD_COLOR : IMREAD_GRAYSCALE; + std::string blackPath = param.Flat_BwPath; + std::string whitePath = param.Flat_WhitePath; + std::string lutsavePath = param.LutPath; + printf("\n blackPath =%s \ + whitePath =%s \ + lutsavePath =%s \n",param.Flat_BwPath.c_str(),param.Flat_WhitePath.c_str(),param.LutPath.c_str()); + cv::Mat lut; + cv::Mat twMat = cv::imread(whitePath, IMREAD_ANYCOLOR); + cv::Mat tbMat = cv::imread(blackPath, IMREAD_ANYCOLOR); + cv::Mat wMat, bMat; + if (mode == 1) + { + wMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, twMat.data); + bMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, tbMat.data); + } + else + { + wMat = twMat; + bMat = tbMat; + } + + //lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), dpi, mode); // add by liuyong: 刘丁维提供 2019/4/12 + lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat),false); + // Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1); + // memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256); + cv::imwrite(param.LutPath, lut); + lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat),true); + cv::imwrite(param.TextLutPath, lut); + printf("exit creatLUTData \n"); +} + +void creatLUTData(int dpi, int mode) +{ + printf("eneter creatLUTData \n"); + auto param = GetFpgaparam(dpi, mode); + auto colormode = mode == 1 ? IMREAD_COLOR : IMREAD_GRAYSCALE; + std::string blackPath = param.Flat_BwPath; + std::string whitePath = param.Flat_WhitePath; + std::string lutsavePath = param.LutPath; + cv::Mat lut; + cv::Mat twMat = cv::imread(whitePath, IMREAD_ANYCOLOR); + cv::Mat tbMat = cv::imread(blackPath, IMREAD_ANYCOLOR); + cv::Mat wMat, bMat; + if (mode == 1) + { + wMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, twMat.data); + bMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, tbMat.data); + } + else + { + wMat = twMat; + bMat = tbMat; + } + + //lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), dpi, mode); // add by liuyong: 刘丁维提供 2019/4/12 + lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat),false); + // Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1); + // memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256); + cv::imwrite(param.LutPath, lut); + lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat),true); + cv::imwrite(param.TextLutPath, lut); + printf("exit creatLUTData \n"); +} + +FPGAConfigParam GetFpgaparam(int dpi, int mode) +{ + FPGAConfigParam param = CorrectParam().GetFpgaparam(dpi, mode); + return param; +} + +void SaveFpgaparam(FPGAConfigParam ¶m) +{ + CorrectParam().SaveCorrectParam(param); +} + +cv::Mat colMean(const cv::Mat& image) +{ + cv::Mat meanMat(1, image.step, CV_8UC1); + cv::Mat tempMat(image.rows, image.step, CV_8UC1, image.data); + for (int i = 0; i < tempMat.step; i++) + meanMat.data[i] = cv::mean(tempMat(cv::Rect(i, 0, 1, tempMat.rows)))[0]; + + return meanMat; +} + +float gamma(float value, float ex) +{ + return cv::pow(value / 255.0f, 1.0f / ex) * 255.0f + 0.5f; +} + +#define GAMMA_EX 1.7f +#define BLACK_OFFSET 5 +void fittingLUT(const std::vector& points, uchar min_value, uchar max_value, uchar* data) +{ + float step = max_value - min_value + 1; + memset(data, min_value, 127); + memset(data + 127, max_value, 129); + int b = points[0]; + int w = points[1]; + int tb = min_value; + int tw = max_value; + + step = cv::max((float)(tw - tb + 1) / (float)(w - b + 1), 0.0f); + float temp; + for (int j = 0, length = (255 - b + 1); j < length; j++) + { + temp = gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET; + data[j + b] = cv::min(255, cv::max(0, static_cast(temp))); + } +} + +cv::Mat calcLUT(const cv::Mat& black, const cv::Mat& white, bool isTextCorrection) +{ + std::vector w; + w.push_back(colMean(black)); + w.push_back(colMean(white)); + cv::Mat lut = createLUT(w, isTextCorrection); + + for (size_t i = 0, block = lut.rows / CHANNEL; i < block; i++) + { + cv::Mat lutROI = lut(cv::Rect(0, i * CHANNEL, 256, CHANNEL)); + cv::Mat tran; + cv::transpose(lutROI, tran); + memcpy(lutROI.data, tran.data, tran.total()); + } + return lut; +} + +cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, int dpi, bool colormode) +{ + #ifndef USE_NEWFLAT + if (black.empty() || white.empty() || black.channels() != 1 || white.channels() != 1 || black.step != white.step) + return cv::Mat(); + + int channel = 1; + if (black.step == 4896 || black.step == 7344) + channel = 408; + else if (black.step == 14688 || black.step == 22032 ||black.step == 44064) + channel = 432; //486 + + if (channel == 1) + return cv::Mat(); + + const int rows = black.cols / channel; + const int cols = 256; + auto cc = CV_8UC(channel); + Mat lut(rows, cols, CV_8UC(channel)); + const double gain = 255.0/((double)CorrectParam().GetFpgaparam(dpi,colormode).MaxBright); + for (size_t i = 0; i < rows; i++) + { + Mat lut_row = lut(cv::Rect(0, i, cols, 1)); + unsigned char *ptr_buffer = lut_row.data; + unsigned char *ptr_black = black.data + i * channel; + unsigned char *ptr_white = white.data + i * channel; + for (size_t j = 0; j < cols; j++) + for (size_t k = 0; k < channel; k++) + { + if (ptr_black[k] >= ptr_white[k]) + { + ptr_buffer[j * channel + k] = 0; + continue; + } + + if (j <= ptr_black[k]) + ptr_buffer[j * channel + k] = 0; + else if (j >= ptr_white[k]) + ptr_buffer[j * channel + k] = 255; + else + { + float val = 255.0f * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]) * gain; + ptr_buffer[j * channel + k] = (unsigned char)cv::max(0.0f, cv::min(val, 255.0f)); + } + } + } + cv::Mat saveMat(black.step, 256, CV_8UC1, lut.data); + return saveMat.clone(); + #else + return calcLUT(black,white,false); + #endif +} + +std::vector caculate(const std::vector& points_x, const std::vector& points_y) +{ + int MaxElement = points_x.size() - 1; + //计算常数f + double f = points_y[0]; + //求解 + int n, m; + //double a[MaxElement][MaxElement+1]; + std::vector> a; + //a.resize(MaxElement); + for (int i = 0; i < MaxElement; i++) + { + std::vector b; + b.resize(MaxElement + 1); + a.push_back(b); + } + + for (int i = 0; i < MaxElement; i++) + { + for (int j = 0; j < MaxElement; j++) + a[i][j] = cv::pow(points_x[i + 1], MaxElement - j); + a[i][MaxElement] = points_y[i + 1] - f; + } + + int i, j; + n = MaxElement; + + for (j = 0; j < n; j++) + { + double max = 0; + double imax = 0; + for (i = j; i < n; i++) + { + if (imax < cv::abs(a[i][j])) { + imax = cv::abs(a[i][j]); + max = a[i][j];//得到各行中所在列最大元素 + m = i; + } + } + if (cv::abs(a[j][j]) != max) + { + double b = 0; + for (int k = j; k < n + 1; k++) { + b = a[j][k]; + a[j][k] = a[m][k]; + a[m][k] = b; + } + } + + for (int r = j; r < n + 1; r++) + { + a[j][r] = a[j][r] / max;//让该行的所在列除以所在列的第一个元素,目的是让首元素为1 + } + + for (i = j + 1; i < n; i++) + { + double c = a[i][j]; + if (c == 0.0) continue; + for (int s = j; s < n + 1; s++) { + a[i][s] = a[i][s] - a[j][s] * c;//前后行数相减,使下一行或者上一行的首元素为0 + } + } + } + for (i = n - 2; i >= 0; i--) + { + for (j = i + 1; j < n; j++) + { + a[i][n] = a[i][n] - a[j][n] * a[i][j]; + } + } + + std::vector result; + for (int k = 0; k < n; k++) + result.push_back(a[k][n]); + result.push_back(f); + return result; +} + +cv::Mat createLUT(const std::vector& mats, bool isTextCorrect) +{ + int rows = mats[0].cols; + cv::Mat lut(rows, 256, CV_8UC1); + + double max_val, min_val; + cv::minMaxIdx(mats[0], &min_val, nullptr); + cv::minMaxIdx(mats[1], nullptr, &max_val); + for (size_t i = 0; i < rows; i++) + { + std::vector grayPoints; + for (size_t j = 0; j < mats.size(); j++) + grayPoints.push_back(mats[j].data[i]); + + fittingLUT(grayPoints, static_cast(min_val), static_cast(max_val), lut.data + i * 256); + } + if (isTextCorrect) + { + std::vector points_x = { 0, 25, 230, 255 }, points_y = { 0, 0, 255, 255 }; + std::vector coefficient = caculate(points_x, points_y); + + uchar buffer[256]; + for (int i = 0; i < 256; i++) + { + int temp = coefficient[0] * i * i * i + coefficient[1] * i * i + coefficient[2] * i + coefficient[3]; + buffer[i] = static_cast(cv::min(255, cv::max(0, temp))); + } + + cv::Mat lut_lut(256, 1, CV_8UC1, buffer); + cv::LUT(lut, lut_lut, lut); + } + return lut; +} \ No newline at end of file diff --git a/device/gxx-linux/capimage/correct_ultis.h b/device/gxx-linux/capimage/correct_ultis.h new file mode 100644 index 0000000..27859fd --- /dev/null +++ b/device/gxx-linux/capimage/correct_ultis.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include +#include "CameraParam.h" + +static cv::Mat lutGrayMat; //灰色校正值 +static cv::Mat lutColorMat; //彩色校正值 +static int offsetStep[12]; +static int expStep[2][3]; + +void initStep(); + +cv::Mat calcLUT(const cv::Mat& black, const cv::Mat& white, bool isTextCorrection); + +cv::Mat extractRepresentRow2(const cv::Mat& src); + +void initLut(const std::string lutpath,bool iscolor); + +cv::Mat createLUT(const std::vector& mats, bool isTextCorrect); + +void correctColor(cv::Mat& src, int dpi,int mode,bool isText); + +void creatLUTData(int dpi , int mode); + +void creatLUTData(int dpi , int mode,FPGAConfigParam param); + +FPGAConfigParam GetFpgaparam(int dpi,int mode); + +void SaveFpgaparam(FPGAConfigParam& param); + +cv::Mat create_lut(const cv::Mat& black, const cv::Mat& white,int dpi, bool colormode); + +void correctColor(cv::Mat& src, int dpi, int mode,bool isText); \ No newline at end of file diff --git a/device/gxx-linux/capimage/gvideo.h b/device/gxx-linux/capimage/gvideo.h index e0da620..5e07a63 100644 --- a/device/gxx-linux/capimage/gvideo.h +++ b/device/gxx-linux/capimage/gvideo.h @@ -38,7 +38,7 @@ protected: size_t length; }; - const int v4l_buffer_count = 5; + const int v4l_buffer_count = 3; int v4l_width = 3100; int v4l_height = 3100; std::string dev_name; diff --git a/device/gxx-linux/capimage/gvideoisp1.cpp b/device/gxx-linux/capimage/gvideoisp1.cpp index e9df0f7..89ff4d8 100644 --- a/device/gxx-linux/capimage/gvideoisp1.cpp +++ b/device/gxx-linux/capimage/gvideoisp1.cpp @@ -172,6 +172,7 @@ void* GVideoISP1::read_frame(int timeout) { LOG_TRACE(string_format("VIDIOC_QBUF sucess")); } LOG_TRACE(string_format("buf.index = %d,buf.addr = %p\n",buf.index,buffers[buf.index].start)); + printf("\n readframe size = %d ",buffers[buf.index].length); return buffers[buf.index].start; } diff --git a/device/gxx-linux/capimage/hgutils.cpp b/device/gxx-linux/capimage/hgutils.cpp index cc01014..48dfd06 100644 --- a/device/gxx-linux/capimage/hgutils.cpp +++ b/device/gxx-linux/capimage/hgutils.cpp @@ -3,10 +3,11 @@ #include #include #include +#include "CImageMerge.h" using namespace cv; -cv::Mat extractRepresentRow2(const cv::Mat &src) +cv::Mat extractRepresentRow(const cv::Mat &src) { printf("extractRepresentRow2 enter \n"); Mat src_temp(src.rows, src.step, CV_8UC1, src.data); @@ -137,9 +138,9 @@ cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, bool colormode, C void initLut() { if(access(LUT_GRAY_LUT_PATH, F_OK) != -1) - lutGrayMat = cv::imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE); //灰色校正值 + lutGrayMat_old = cv::imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE); //灰色校正值 if(access(LUT_COLOR_LUT_PATH, F_OK) != -1) - lutColorMat = cv::imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE); //彩色校正值 + lutColorMat_old = cv::imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE); //彩色校正值 } void correctColor(cv::Mat src, bool enhance) @@ -153,11 +154,11 @@ void correctColor(cv::Mat src, bool enhance) if (src.type() == CV_8UC3) { patch = (src.cols * 3) / SIZE; - if (lutColorMat.empty()) + if (lutColorMat_old.empty()) { if (access(LUT_COLOR_LUT_PATH, F_OK) != -1) { - lutColorMat = imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE); + lutColorMat_old = imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE); } else { @@ -165,16 +166,16 @@ void correctColor(cv::Mat src, bool enhance) return; } } - lutMat = lutColorMat; + lutMat = lutColorMat_old; } else { patch = (src.cols) / SIZE; - if (lutGrayMat.empty()) + if (lutGrayMat_old.empty()) { if (access(LUT_GRAY_LUT_PATH, F_OK) != -1) { - lutGrayMat = imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE); + lutGrayMat_old = imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE); } else { @@ -182,7 +183,7 @@ void correctColor(cv::Mat src, bool enhance) return; } } - lutMat = lutGrayMat; + lutMat = lutGrayMat_old; } if (lutMat.empty()) { @@ -218,7 +219,7 @@ void creatLUTData(int mode, CISVendor vendor) bMat = tbMat; } - lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), mode, vendor); // add by liuyong: 刘丁维提供 2019/4/12 + lut = create_lut(extractRepresentRow(bMat), extractRepresentRow(wMat), mode, vendor); // add by liuyong: 刘丁维提供 2019/4/12 Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1); memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256); cv::imwrite(lutsavePath, dst); @@ -261,7 +262,7 @@ cv::Mat GetMergeMat(void *data, int width, int height, int type) return saveMat.clone(); } - +//3399 旧版本 华凌cis拼接算法 cv::Mat GetMergeMat(cv::Mat& mat, int width, int height, int type) { if (mat.empty()) @@ -288,6 +289,38 @@ cv::Mat GetMergeMat(cv::Mat& mat, int width, int height, int type) return mat; } +cv::Mat GetStitchMat(int pixtype,int width,int height,cv::Mat& mat){ + cv::Mat dst; + cv::Mat ch_mats[3]; + int dstwidth, dstheight; + width = width /3 /(pixtype == 1? 3:1); + height *=3; + dstwidth = width * 3; + dstheight = height / 3; + if (pixtype == IMAGE_COLOR) + { + //mat = cv::Mat(m_height / 3, m_width * 9, CV_8UC1, imgdata); + dst = cv::Mat(dstheight, dstwidth, CV_8UC3); + ch_mats[2] = mat(cv::Rect(width * 3 * 1, 0, width * 3, height / 3)); //R 对应红通道 + ch_mats[1] = mat(cv::Rect(width * 3 * 2, 0, width * 3, height / 3)); //G 对应绿通道 + ch_mats[0] = mat(cv::Rect(width * 3 * 0, 0, width * 3, height / 3)); //B 对应蓝通道 + cv::merge(ch_mats, 3, dst); + for (int i = 0; i < 3; i++) + ch_mats[i].release(); + return dst.clone(); + } + else + { //gray + return mat; + } +} + +//3399 敦南cis 300 600 拼接算法 +cv::Mat GetMergeMat(int dstwidth ,int dstheight,int type,cv::Mat& mat,std::uint32_t fpga_vs) +{ + return CImageMerge().MergeImage(type==CV_8UC3,mat,dstwidth,dstheight,0x90001); +} + void savescannerinfo(ScannerNativeParam params) { jsonconfig().savescannerinfo(params); diff --git a/device/gxx-linux/capimage/hgutils.h b/device/gxx-linux/capimage/hgutils.h index 912f1fb..471c30d 100644 --- a/device/gxx-linux/capimage/hgutils.h +++ b/device/gxx-linux/capimage/hgutils.h @@ -4,10 +4,10 @@ #include "commondef.h" -static cv::Mat lutGrayMat; //灰色校正值 -static cv::Mat lutColorMat; //彩色校正值 +static cv::Mat lutGrayMat_old; //灰色校正值 +static cv::Mat lutColorMat_old; //彩色校正值 -cv::Mat extractRepresentRow2(const cv::Mat& src); +cv::Mat extractRepresentRow(const cv::Mat& src); cv::Mat create_lut(const cv::Mat& black, const cv::Mat& white,bool colormode,CISVendor vendor); @@ -19,8 +19,13 @@ cv::Mat GetMergeMat(void* data,int width ,int height,int type); cv::Mat GetMergeMat(cv::Mat& mat,int width ,int height,int type); +cv::Mat GetMergeMat(int dstwidth ,int dstheight,int type,cv::Mat& mat,std::uint32_t fpga_vs); + +cv::Mat GetStitchMat(int pixtype,int width,int height,cv::Mat& mat); + void correctColor(cv::Mat src, bool enhance); + void creatLUTData(int mode,CISVendor vendor); void savescannerinfo(ScannerNativeParam params); diff --git a/device/gxx-linux/capimage/jsonconfig.cpp b/device/gxx-linux/capimage/jsonconfig.cpp index 842d322..0f67b80 100644 --- a/device/gxx-linux/capimage/jsonconfig.cpp +++ b/device/gxx-linux/capimage/jsonconfig.cpp @@ -9,6 +9,7 @@ #define SP_COLOR_DEFAULT 0x438 #define SP_GRAY_DEFAULT 0xca8 + jsonconfig::jsonconfig() { } @@ -24,7 +25,7 @@ void jsonconfig::savecisconfig(HGCorrectConfigs configs) auto ret = mkdir(JSON_CORRECTDIR_PATH, 0777); if (ret != 0) { - HG_LOG("make dir failed .path=%s \n", JSON_CORRECTDIR_PATH); + printf("make dir failed .path=%s \n", JSON_CORRECTDIR_PATH); } } json m_json; @@ -100,6 +101,7 @@ HGCorrectConfigs jsonconfig::getcorrectconfigs() std::ifstream i(JSON_CORRECTFILE_PATH); auto pos = i.tellg(); i.seekg(0, std::ios::end); + //printf("file length =%d ", i.tellg()); if (i.tellg() <= 2) { cfs = getdefaultconfigs(); @@ -226,17 +228,19 @@ void jsonconfig::savescannerinfo(ScannerNativeParam param) m_json[S_INFO_PID] = (param.Pid); std::ofstream o(JSON_SCANNER_INFO_FILE); o << std::setw(4) << m_json << std::endl; + //printf("\n %s speedmode value = %d",JSON_SCANNER_INFO_FILE,param.speedmode); } ScannerNativeParam jsonconfig::getscannerinfo() { + std::lock_guard lc(mtx); ScannerNativeParam snp; if (access(JSON_SCANNER_INFO_DIR, 0) == -1) { auto ret = mkdir(JSON_SCANNER_INFO_DIR, 0777); if (ret != 0) { - HG_LOG("make dir failed .path=%s \n", JSON_SCANNER_INFO_DIR); + printf("make dir failed .path=%s \n", JSON_SCANNER_INFO_DIR); } } @@ -253,6 +257,7 @@ ScannerNativeParam jsonconfig::getscannerinfo() i.seekg(0, std::ios::end); + //printf("file length =%d ", i.tellg()); if (i.tellg() <= 2) { snp = getdefaultscannerinfo(); @@ -333,7 +338,7 @@ ScannerNativeParam jsonconfig::getscannerinfo() if(!m_json[S_INFO_SLEEPTIME].is_null()) m_json[S_INFO_SLEEPTIME].get_to(snp.sleeptime); else - snp.sleeptime = 900; + snp.sleeptime = 10800; if(!m_json[S_INFO_CLR_MAXBRT].is_null()) m_json[S_INFO_CLR_MAXBRT].get_to(snp.clr_maxbright); @@ -357,8 +362,12 @@ ScannerNativeParam jsonconfig::getscannerinfo() { #ifdef G100 snp.Pid = 0x139; - #else + #elif defined G200 snp.Pid = 0x239; + #elif defined G300 + snp.Pid = 0x339; + #else + snp.Pid = 0x439; #endif } @@ -366,6 +375,8 @@ ScannerNativeParam jsonconfig::getscannerinfo() m_json[S_INFO_VID].get_to(snp.Vid); else snp.Vid = 0x3072; + + //printf("vid = %d pid =%d \n",snp.Vid,snp.Pid ); return snp; } @@ -385,14 +396,24 @@ ScannerNativeParam jsonconfig::getdefaultscannerinfo() param.color_sp=0x27C; param.speedmode = 100; param.Pid = 0x0239; -#else +#elif defined G100 param.gray_sp=0x822; //G200 140 ppm 0x27c 0x781 G100 100 ppm 0x2B6 0x822 param.color_sp=0x2B6; param.speedmode = 70; param.Pid = 0x0139; +#elif defined G300 + param.gray_sp=0x822; + param.color_sp=0x2B6; + param.speedmode = 40; + param.Pid = 0x0339; +#else + param.gray_sp=0x822; + param.color_sp=0x2B6; + param.speedmode = 50; + param.Pid = 0x0439; #endif param.Vid = 0x3072; - param.sleeptime=3600; + param.sleeptime=10800; param.clr_maxbright = param.gray_maxbright = 200; return param; diff --git a/device/gxx-linux/capimage/jsonconfig.h b/device/gxx-linux/capimage/jsonconfig.h index deffaca..1a43092 100644 --- a/device/gxx-linux/capimage/jsonconfig.h +++ b/device/gxx-linux/capimage/jsonconfig.h @@ -1,6 +1,7 @@ #pragma once #include "json.hpp" #include "commondef.h" +#include using json = nlohmann::json; @@ -18,4 +19,5 @@ public: ScannerNativeParam getscannerinfo(); HGCorrectConfigs getdefaultconfigs(); ScannerNativeParam getdefaultscannerinfo(); + std::mutex mtx; }; diff --git a/device/gxx-linux/capimage/scannersysinfo.h b/device/gxx-linux/capimage/scannersysinfo.h new file mode 100644 index 0000000..23d8ac1 --- /dev/null +++ b/device/gxx-linux/capimage/scannersysinfo.h @@ -0,0 +1,69 @@ +#pragma once +#include + +enum class SysType +{ + Sys_Linux_Debian=1, + Sys_Linux_Uos, + Sys_Android +}; + +enum class Scanner_Serial{ + S_G100=1, + S_G200, + S_G300, + S_G300_UV, + S_G400 +}; + +enum class SCPU +{ + CPU_3288=1, + CPU_3399 +}; + + +enum class SMBType +{ + MB_DRV_UNKNOWUN, + MB_DRV_8825, + MB_DRV_TMC216, + MB_DRV_ANLU, + MB_DRV_LATIACE +}; + +enum class HGCISType +{ + CIS_UNKOWNUN, + CIS_HUALIN_MONO_V0, + CIS_DUNNAN_MONO_V0, + CIS_DUNNAN_COLOR_V0 +}; + +enum class ScreenType +{ + ST_None=1, + ST_SmallLcd, + ST_BigLcd, + ST_8Inch, + ST_7Inch +}; + +typedef struct Scanner_SysInfo +{ + SCPU CPU;//3288 3399 + SysType Systype; + ScreenType Screentype; + unsigned int MtBoardVersion; + SMBType MtType; + unsigned int FPGAVersion; + HGCISType Cistype; + unsigned int ResSup[3];//分辨率支持 + unsigned int MemTotal;//单位 MB + unsigned int DiskTotal;//单位 MB + unsigned int DiskUsed;//已使用空间 + std::string KernelVersion; + unsigned int Have_EthernPort; + std::string ServiceVersion; + float UsbProtocol;//1.0 2.0 2.xx +}ScannerSysInfo; diff --git a/device/gxx-linux/capimage/xmake.lua b/device/gxx-linux/capimage/xmake.lua index 09de6fe..8465f32 100644 --- a/device/gxx-linux/capimage/xmake.lua +++ b/device/gxx-linux/capimage/xmake.lua @@ -5,6 +5,6 @@ target("capimage") add_files("*.cpp") add_deps("regs", "deviceio", "conf", "applog", {public = true}) add_includedirs(".", { public = true}) - add_links("opencv_core", "opencv_highgui", "opencv_imgproc", { public = true }) + add_links("opencv_core", "opencv_imgcodecs", "opencv_highgui", "opencv_imgproc", { public = true }) add_syslinks("pthread") add_packages("common") \ No newline at end of file diff --git a/device/gxx-linux/deviceio/DevUtil.h b/device/gxx-linux/deviceio/DevUtil.h index 553f747..4ec2b08 100644 --- a/device/gxx-linux/deviceio/DevUtil.h +++ b/device/gxx-linux/deviceio/DevUtil.h @@ -3,7 +3,6 @@ #include #include -#define G300 template void write_dev(std::string path, T value) diff --git a/device/gxx-linux/deviceio/PinMonitor.cpp b/device/gxx-linux/deviceio/PinMonitor.cpp index cd48c13..2c7249e 100644 --- a/device/gxx-linux/deviceio/PinMonitor.cpp +++ b/device/gxx-linux/deviceio/PinMonitor.cpp @@ -3,35 +3,30 @@ #include #include #include -#include #include #include #include "StopWatch.h" -#include -#include -#include "applog.h" -#include "stringex.hpp" -static const std::string loggername = "PinMonitor"; PinMonitor::PinMonitor(unsigned int pinNum, std::function call_back) - : pin(pinNum) +: pin(pinNum) { - LOG_INIT(); pin.setDirection(Gpio::in); pin.setEdge(Gpio::falling); this->call_back = call_back; thread_monitor = std::thread(&PinMonitor::monitor, this); //printf("PinMonitor threadid = %d \n",thread_monitor.get_id()); - // int priority=sched_get_priority_max(SCHED_FIFO); - // if(priority==-1) - // { - // printf("sched_get_priority_max error \n"); - // } - // thparm.sched_priority = priority; - // if(pthread_setschedparam(thread_monitor.native_handle(),SCHED_FIFO,&thparm)) - // { - // printf("failed to error set pthread_setschedparam \n"); - // } + sched_param thparm; + int priority=sched_get_priority_max(SCHED_FIFO); + if(priority==-1) + { + printf("sched_get_priority_max error \n"); + } + thparm.sched_priority = priority; + if(pthread_setschedparam(thread_monitor.native_handle(),SCHED_FIFO,&thparm)) + { + printf("failed to error set pthread_setschedparam \n"); + } + } PinMonitor::~PinMonitor() @@ -66,20 +61,15 @@ void PinMonitor::monitor() { lseek(pfd.fd, 0, SEEK_SET); num = read(pfd.fd, buf, 8); - + buf[num - 1] = '\0'; ret = atoi(buf); - //LOG_TRACE("poll call"); - if (call_back) - { - sw.reset(); - call_back(pin.getPort()); - LOG_TRACE(string_format("poll call times = %.2f \n",sw.elapsed_ms())); - } - + if (call_back) + call_back(pin.getPort()); + sw.reset(); - while(sw.elapsed_ms() < 10) + while(sw.elapsed_ms() < 30) { ret = poll(&pfd, 1, 1); if (ret > 0) @@ -88,43 +78,11 @@ void PinMonitor::monitor() buf[num - 1] = '\0'; ret = atoi(buf); //printf("pMonitor nread = %d ret val = %d \n",num,ret); - } + } } } } } close(pfd.fd); - - // int n; - // int epfd = epoll_create(1); - // int fd = open(pin.getValuePath().c_str(), O_RDONLY); - // char buf[8]; - // //printf("open returned %d: %s\n", fd, strerror(errno)); - // if (fd > 0) - // { - // struct epoll_event ev; - // struct epoll_event events; - // ev.events = EPOLLPRI; - // ev.data.fd = fd; - - // n = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev); - - // while (bMonitor) - // { - // n = epoll_wait(epfd, &events, 1, 1000); - - // if (n > 0) - // { - // n = lseek(fd, 0, SEEK_SET); - // n = read(fd, buf, 8); - - // buf[n - 1] = '\0'; - // auto ret = atoi(buf); - // if (call_back) - // call_back(pin.getPort()); - // } - // } - // } - // close(fd); } \ No newline at end of file diff --git a/device/gxx-linux/imgproc/imageencode.cpp b/device/gxx-linux/imgproc/imageencode.cpp index 2390c94..68b4c8a 100644 --- a/device/gxx-linux/imgproc/imageencode.cpp +++ b/device/gxx-linux/imgproc/imageencode.cpp @@ -22,18 +22,22 @@ MemoryPtr BmpImageEncode::encode(cv::Mat &image) return mem; } -JpegImageEncode::JpegImageEncode(bool bwimg) +JpegImageEncode::JpegImageEncode(bool bwimg, int dpi) { - // if (!bwimg) - // { - // compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); - // compression_params.push_back(100); - // } - // else{ - // compression_params.push_back(/*CV_IMWRITE_PNG_STRATEGY*/17); - // compression_params.push_back(cv::IMWRITE_PNG_STRATEGY_FIXED); - // } - // m_bwimg = bwimg; + if (!bwimg) + { + compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); + compression_params.push_back(100); + compression_params.push_back(/*cv::CV_IMWRITE_JPEG_RESOLUTION_X*/7); + compression_params.push_back(dpi); + compression_params.push_back(/*cv::CV_IMWRITE_JPEG_RESOLUTION_Y*/8); + compression_params.push_back(dpi); + } + else{ + compression_params.push_back(/*CV_IMWRITE_PNG_STRATEGY*/17); + compression_params.push_back(cv::IMWRITE_PNG_STRATEGY_FIXED); + } + m_bwimg = bwimg; } JpegImageEncode::~JpegImageEncode() @@ -42,11 +46,11 @@ JpegImageEncode::~JpegImageEncode() MemoryPtr JpegImageEncode::encode(cv::Mat &image) { VectorMemroyPtr mem = VectorMemroyPtr(new VectorMemroy()); - StopWatch sw; + // StopWatch sw; printf("encode image(%d * %d): %p - %p\n", image.cols, image.rows, image.data, image.dataend); // cv::imwrite("beforcompress.jpg",image); // cv::imencode(m_bwimg ? ".png" : ".jpg", image, mem->buf(), compression_params); - cv::imencode(".png", image, mem->buf(), compression_params); + cv::imencode(".jpg", image, mem->buf(), compression_params); //printf("encode time = %0.2f \n", sw.elapsed_ms()); return mem; diff --git a/device/gxx-linux/imgproc/imageencode.h b/device/gxx-linux/imgproc/imageencode.h index f98b62f..6b3f3b7 100644 --- a/device/gxx-linux/imgproc/imageencode.h +++ b/device/gxx-linux/imgproc/imageencode.h @@ -21,7 +21,7 @@ public: class JpegImageEncode : public IImageEncode { public: - JpegImageEncode(bool bwimg); + JpegImageEncode(bool bwimg, int dpi); virtual ~JpegImageEncode(); virtual MemoryPtr encode(cv::Mat& image); diff --git a/device/gxx-linux/motor_run/CuoZhiMotor.cpp b/device/gxx-linux/motor_run/CuoZhiMotor.cpp new file mode 100644 index 0000000..de9bf86 --- /dev/null +++ b/device/gxx-linux/motor_run/CuoZhiMotor.cpp @@ -0,0 +1,64 @@ +#include "CuoZhiMotor.h" +#include + +CuoZhiMotor::CuoZhiMotor() : Motor(motorPorts_Cuozhi) +{ + m_cfg.GetParams(0,MotorConfig::MTBDType::MT_DRV); + if(Dail().GetValue().dails.in_voltage4 == 0) + m_mttype = MotorConfig::MTBDType::MT_DRV; + else + m_mttype = MotorConfig::MTBDType::MT_TMC; + speedChange(0,1,1); + printf("\nCuo speed = %d ",m_mttype); +} + +CuoZhiMotor::~CuoZhiMotor() +{ + std::cout << "CuoZhiMotor::~CuoZhiMotor()" << std::endl; +} + +void CuoZhiMotor::speedChange(int speed,int dpi ,int iscolor) +{ + printf("\nCuo speed = %d dpi = %d iscolor = %d",speed,dpi,iscolor); + if(speed == 0xff) + { + if(m_mttype == MotorConfig::MTBDType::MT_DRV) + mspCuozhiForward = { .finalPeriod = 1427500,.Fmin = 2027500 ,.stepnum = 30 ,.a = 100 , + .offset = 4 ,.finalDelay = 3000 }; + else + mspCuozhiForward = { .finalPeriod = 1427500/4,.Fmin = 2027500/4 ,.stepnum = 30 ,.a = 100 , + .offset = 4 ,.finalDelay = 3000 }; + } + else{ + auto params = m_cfg.GetMotorSpeedParams(false,m_mttype); + m_speedmode = speed; + for (int i = 0; i < params.size(); i++) + { + if (params[i].dpi == dpi && + params[i].colormode == iscolor && + params[i].speed == (speed+1)) + { + mspCuozhiForward = { .finalPeriod = params[i].mt_param.finalPeriod,.Fmin = params[i].mt_param.Fmin,.stepnum = params[i].mt_param.stepnum,.a = params[i].mt_param.a, + .offset = params[i].mt_param.offset,.finalDelay = params[i].mt_param.finalDelay }; + } + } + } + + printf("\n mspCuozhiForward.finalPeriod %d, mspCuozhiForward.Fmin %d, mspCuozhiForward.stepnum %f , mspCuozhiForward.a %f, mspCuozhiForward.offset %f , mspCuozhiForward.finalDelay %f", + mspCuozhiForward.finalPeriod, mspCuozhiForward.Fmin, mspCuozhiForward.stepnum, mspCuozhiForward.a, mspCuozhiForward.offset, mspCuozhiForward.finalDelay); + delays_forward = speedup_cfg(mspCuozhiForward.finalPeriod, mspCuozhiForward.Fmin, mspCuozhiForward.stepnum, mspCuozhiForward.a, mspCuozhiForward.offset, mspCuozhiForward.finalDelay); + + // if(cuoZhiForwardFinalPeriod.find(dpi) == cuoZhiForwardFinalPeriod.end()) + // dpi = 1; + // mspCuozhiForward = { .finalPeriod = cuoZhiForwardFinalPeriod.at(dpi)[m_speedmode],.Fmin = cuoZhiFmin.at(dpi)[m_speedmode], + // .stepnum = cuoZhiStepNum.at(dpi)[m_speedmode],.a = cuoZhiA.at(dpi)[m_speedmode],.offset = cuoZhiOffset.at(dpi)[m_speedmode], + // .finalDelay = cuoZhiFinalDelay.at(dpi)[m_speedmode] }; + mspCuozhiBackward = { .finalPeriod = cuoZhiBackwardFinalPeriod.at(dpi)[m_speedmode],.Fmin = cuoZhiFmin.at(dpi)[m_speedmode], + .stepnum = cuoZhiStepNum.at(dpi)[m_speedmode],.a = cuoZhiA.at(dpi)[m_speedmode],.offset = cuoZhiOffset.at(dpi)[m_speedmode], + .finalDelay = cuoZhiFinalDelay.at(dpi)[m_speedmode] }; + // delays_forward = speedup_cfg(mspCuozhiForward.finalPeriod, mspCuozhiForward.Fmin, mspCuozhiForward.stepnum, mspCuozhiForward.a, + // mspCuozhiForward.offset, mspCuozhiForward.finalDelay); + delays_backward = speedup_cfg(mspCuozhiBackward.finalPeriod, mspCuozhiBackward.Fmin, mspCuozhiBackward.stepnum, mspCuozhiBackward.a, + mspCuozhiBackward.offset, mspCuozhiBackward.finalDelay); + + } \ No newline at end of file diff --git a/device/gxx-linux/motor_run/CuoZhiMotor.h b/device/gxx-linux/motor_run/CuoZhiMotor.h new file mode 100644 index 0000000..dd89e44 --- /dev/null +++ b/device/gxx-linux/motor_run/CuoZhiMotor.h @@ -0,0 +1,92 @@ +#pragma once +#include "Motor.h" +#include + +class CuoZhiMotor : public Motor +{ +public: + CuoZhiMotor(); + ~CuoZhiMotor(); + void speedChange(int speed,int dpi ,int iscolor); + void reset() { + mspCuozhiBackward = {.finalPeriod = 827500, .Fmin = 1407750, .stepnum = 25, .a = 150, .offset = 8, .finalDelay = 3000}; + mspCuozhiForward = {.finalPeriod = 627500, .Fmin = 1407750, .stepnum = 25, .a = 150, .offset = 8, .finalDelay = 3000}; + if(m_mttype == MotorConfig::MTBDType::MT_TMC) + { + mspCuozhiBackward.finalPeriod /= 4; + mspCuozhiBackward.Fmin /= 4; + mspCuozhiForward.finalPeriod /= 4; + mspCuozhiForward.Fmin /= 4; + } + delays_forward = speedup_cfg(mspCuozhiForward.finalPeriod, mspCuozhiForward.Fmin, mspCuozhiForward.stepnum, mspCuozhiForward.a, + mspCuozhiForward.offset, mspCuozhiForward.finalDelay); + forward(); + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + stop(); + delays_backward = speedup_cfg(mspCuozhiBackward.finalPeriod, mspCuozhiBackward.Fmin, mspCuozhiBackward.stepnum, mspCuozhiBackward.a, + mspCuozhiBackward.offset, mspCuozhiBackward.finalDelay); + backward(); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + stop(); + } + + virtual void start() { + forward(); + } + + void forward() { + setDirection(1); + Motor::start(delays_forward, mspCuozhiForward); + } + + void backward() { + setDirection(0); + Motor::start(delays_backward, mspCuozhiBackward); + } + +private: + MotorConfig m_cfg; + const std::map> cuoZhiStepNum = { + {1,{23,25,30,30,30 }}, + {2,{23,25,30,30,30 }}, + {3,{23,25,30,30,30 }}, + }; + const std::map> cuoZhiForwardFinalPeriod = { + {1,{607500,537500,477500,435500,435500}}, + {2,{607500,537500,517500,497500,477500}}, + {3,{607500,537500,527500,477500,307500}}, + };//627500,607500,587500,567500,547500,527500 + const std::map> cuoZhiBackwardFinalPeriod = { + {1,{607500,537500,477500,395500,307500}}, + {2,{607500,587500,527500,477500,307500}}, + {3,{607500,587500,527500,477500,307500}}, + };//707500,607500,587500,567500,547500,527500 + const std::map> cuoZhiFmin = { + {1,{ 1407750,1407750,1407750,1407750,1407750 }}, + {2,{ 1407750,1407750,1407750,1407750,1407750 }}, + {3,{ 1407750,1407750,1407750,1407750,1407750 }}, + }; + const std::map> cuoZhiA = { + {1,{ 180,150,150,130,130 }}, + {2,{ 180,150,150,130,130 }}, + {3,{ 180,150,150,150,150 }}, + }; + const std::map> cuoZhiOffset = { + {1,{ 7,7,7,12,12 }}, + {2,{ 7,7,7,7,7 }}, + {3,{ 7,7,7,7,7 }}, + }; + const std::map> cuoZhiFinalDelay = { + {1,{ 3000,3000,3000,3000,3000 }}, + {2,{ 3000,3000,3000,3000,3000 }}, + {3,{ 3000,3000,3000,3000,3000 }}, + }; + + MotorSpeedParam mspCuozhiForward; + MotorSpeedParam mspCuozhiBackward; + std::vector delays_forward; + std::vector delays_backward; + int m_speedmode; +}; + + diff --git a/device/gxx-linux/motor_run/DevUtil.cpp b/device/gxx-linux/motor_run/DevUtil.cpp new file mode 100644 index 0000000..310aca3 --- /dev/null +++ b/device/gxx-linux/motor_run/DevUtil.cpp @@ -0,0 +1,30 @@ +#include "DevUtil.h" +#include + +#define IOEXPORTPATH "/sys/class/gpio/export" +#define PWMEXPORTPATH "/sys/class/pwm/pwmchip%d/export" +int read_dev_i(std::string path) { + int val = -1; + std::ifstream ifin(path.c_str()); + ifin >> val; + return val; +} + +std::string read_dev_s(std::string path) { + std::string val; + std::ifstream ifin(path.c_str()); + ifin >> val; + return val; +} + +DeviceExport::DeviceExport() +{ + int num = sizeof(ports) / sizeof(ports[0]); + for (int i = 0; i < num; i++) + write_dev(IOEXPORTPATH, ports[i]); + + num = sizeof(pwms) / sizeof(pwms[0]); + for (int i = 0; i < num; i++) + write_dev(string_format(PWMEXPORTPATH, pwms[i]), 0); + printf("DeviceExport::DeviceExport().\n"); +} diff --git a/device/gxx-linux/motor_run/DevUtil.h b/device/gxx-linux/motor_run/DevUtil.h new file mode 100644 index 0000000..9018f16 --- /dev/null +++ b/device/gxx-linux/motor_run/DevUtil.h @@ -0,0 +1,57 @@ +#pragma once +#include +#include +#include +#include "stringex.hpp" + +template +void write_dev(std::string path, T value) { + std::ofstream ofout(path); + ofout << value; + ofout.close(); +} + +extern int read_dev_i(std::string path); + +extern std::string read_dev_s(std::string path); + +enum PORTS +{ + /* //RK3288 Motor GPIO + CuoZhiMotor_Reset = 56, // GPIO2_A0 MOTO_BOT_RESET_N + CuoZhiMotor_Sleep = 57, // GPIO2_A1 MOTO_BOT_SLEEP_N + CuoZhiMotor_Enable = 58, // GPIO2_A2 MOTO_BOT_ENBL_N + CuoZhiMotor_Direction = 62, // GPIO2_A6 MOTO_BOT_DIR + CuoZhiMotor_Home = 184, // GPIO6_A0 MOTO_BOT_HOME_N + CuoZhiMotor_Fault = 185, // GPIO6_A1 MOTO_BOT_FAULT_N + + ZouZhiMotor_Reset = 64, // GPIO2_B0 MOTO_TOP_RESET_N + ZouZhiMotor_Sleep = 65, // GPIO2_B1 MOTO_TOP_SLEEP_N + ZouZhiMotor_Enable = 66, // GPIO2_B2 MOTO_TOP_ENBL_N + ZouZhiMotor_Direction = 70, // GPIO2_B6 MOTO_TOP_DIR + ZouZhiMotor_Home = 186, // GPIO6_A2 + ZouZhiMotor_Fault = 187, // GPIO6_A3 + */ + + //RK3399 Motor GPIO + MotorPower = 157, // GPIO4_D5 motor power + + CuoZhiMotor_Reset = 151, // GPIO4_C7 BOT + CuoZhiMotor_Enable = 153, // GPIO4_D1 BOT + CuoZhiMotor_Direction = 152, // GPIO4_D0 BOT + + ZouZhiMotor_Reset = 155, // GPIO4_D3 TOP + ZouZhiMotor_Enable = 154, // GPIO4_D2 TOP + ZouZhiMotor_Direction = 52, // GPIO1_C4 TOP +}; + +class DeviceExport { +public: + DeviceExport(); +private: + const int ports[7] = { MotorPower, CuoZhiMotor_Reset, CuoZhiMotor_Enable, CuoZhiMotor_Direction, + ZouZhiMotor_Reset, ZouZhiMotor_Enable, ZouZhiMotor_Direction, + }; + const int pwms[2] = { 1, 2 }; +}; + diff --git a/device/gxx-linux/motor_run/Gpio.cpp b/device/gxx-linux/motor_run/Gpio.cpp new file mode 100644 index 0000000..8fa9e8d --- /dev/null +++ b/device/gxx-linux/motor_run/Gpio.cpp @@ -0,0 +1,79 @@ +#include +#include "Gpio.h" +#include "DevUtil.h" + +#define IOPATH "%s/gpio%d/%s" + +const std::string Gpio::falling = "falling"; +const std::string Gpio::rising = "rising"; +const std::string Gpio::both = "both"; +const std::string Gpio::none = "none"; + +const std::string Gpio::in = "in"; +const std::string Gpio::out = "out"; + +Gpio::Gpio(int port) +{ + this->port = port; + path_value = string_format(IOPATH, path_gpiobase.c_str(), port, path_value.c_str()); + path_edge = string_format(IOPATH, path_gpiobase.c_str(), port, path_edge.c_str()); + path_direction = string_format(IOPATH, path_gpiobase.c_str(), port, path_direction.c_str()); + path_active_low = string_format(IOPATH, path_gpiobase.c_str(), port, path_active_low.c_str()); + printf("Gpio::Gpio(int port = %d) \n",port); +} + +Gpio::~Gpio() +{ + std::cout << "Gpio::~Gpio()" << std::endl; +} + +int Gpio::getPort() +{ + return port; +} + +void Gpio::setValue(GpioLevel level) +{ + write_dev(path_value, level); +} + +Gpio::GpioLevel Gpio::getValue() { + return (Gpio::GpioLevel)read_dev_i(path_value); +} + +std::string Gpio::getDirection() +{ + return read_dev_s(path_direction); +} + +void Gpio::setDirection(std::string direction) +{ + write_dev(path_direction, direction); +} + +void Gpio::setActive(GpioLevel level) +{ + write_dev(path_active_low, level); +} + +Gpio::GpioLevel Gpio::getActive() +{ + return (GpioLevel)read_dev_i(path_active_low); +} + +void Gpio::setEdge(std::string edge) +{ + write_dev(path_edge, edge); +} + +std::string Gpio::getEdge() +{ + return read_dev_s(path_edge); +} + +GpioOut::GpioOut(int port) : Gpio(port) +{ + setDirection(out); +} + + diff --git a/device/gxx-linux/motor_run/Gpio.h b/device/gxx-linux/motor_run/Gpio.h new file mode 100644 index 0000000..ba785c5 --- /dev/null +++ b/device/gxx-linux/motor_run/Gpio.h @@ -0,0 +1,53 @@ +#pragma once +#include + +class Gpio { +public: + enum GpioLevel { + Low, + High + }; + +public: + static const std::string falling; + static const std::string rising; + static const std::string both; + static const std::string none; + static const std::string in; + static const std::string out; + +public: + Gpio(int port); + ~Gpio(); + int getPort(); + void setValue(GpioLevel level); + GpioLevel getValue(); + std::string getDirection(); + void setDirection(std::string direction); + void setActive(GpioLevel level); + GpioLevel getActive(); + void setEdge(std::string edge); + std::string getEdge(); + + std::string getValuePath() { + return path_value; + } + +private: + const std::string path_gpiobase = "/sys/class/gpio"; + int port; + std::string path_value = "value"; + std::string path_edge = "edge"; + std::string path_direction = "direction"; + std::string path_active_low = "active_low"; + + +}; + +class GpioOut : public Gpio +{ +public: + GpioOut(int port); +}; + + diff --git a/device/gxx-linux/motor_run/Motor.cpp b/device/gxx-linux/motor_run/Motor.cpp new file mode 100644 index 0000000..637ea44 --- /dev/null +++ b/device/gxx-linux/motor_run/Motor.cpp @@ -0,0 +1,69 @@ +#include "Motor.h" +#include "DevUtil.h" +#include +#include +#include + + +const MotorPorts motorPorts_Zouzhi = { .reset = ZouZhiMotor_Reset, .enable = ZouZhiMotor_Enable, .dir = ZouZhiMotor_Direction, + .pwm = 1}; +const MotorPorts motorPorts_Cuozhi = {.reset = CuoZhiMotor_Reset, .enable = CuoZhiMotor_Enable, .dir = CuoZhiMotor_Direction, + .pwm = 2 }; + +std::vector speedup_cfg(int finalPeriod, int Fmin, int stepnum, int a, int offset, int finalDelay) { + std::vector freqs; + int period = 0; + double delay = ((double)finalDelay) / 1000000.0; + double b = stepnum * delay; + for (int i = 0; i < stepnum; i++) { + b = b - delay; + period = (int)(finalPeriod + (Fmin - finalPeriod) / (1 + exp(-a * b + offset))); + freqs.push_back(period); + //printf("\n period %d",period); + } + return freqs; +} + +Motor::Motor(MotorPorts motorPorts) + : powerpin(MotorPower),resetPin(motorPorts.reset),enablePin(motorPorts.enable),dirPin(motorPorts.dir),pwm(motorPorts.pwm) +{ + powerpin.setDirection(Gpio::out); + resetPin.setDirection(Gpio::out); + enablePin.setDirection(Gpio::out); + dirPin.setDirection(Gpio::out); + powerpin.setValue(Gpio::High); + resetPin.setValue(Gpio::High); + enablePin.setValue(Gpio::High); + std::cout << "Motor::Motor(MotorPorts motorPorts)" << std::endl; +} + +Motor:: ~Motor() +{ + stop(); + std::cout << "Motor::~Motor()" << std::endl; +} + +void Motor::start() { + enablePin.setValue(Gpio::Low); + pwm.enable(true); +} + +void Motor::stop() { + enablePin.setValue(Gpio::High); + pwm.enable(false); +} + +void Motor::pause() { + enablePin.setValue(Gpio::Low); + pwm.enable(false); +} + +void Motor::setDirection(int dir) { + dirPin.setValue((Gpio::GpioLevel)dir); +} + +void Motor::setSpeed(int value) { + pwm.setFreq(value); +} + + diff --git a/device/gxx-linux/motor_run/Motor.h b/device/gxx-linux/motor_run/Motor.h new file mode 100644 index 0000000..101d201 --- /dev/null +++ b/device/gxx-linux/motor_run/Motor.h @@ -0,0 +1,72 @@ +#pragma once +#include +#include +#include +#include "Gpio.h" +#include "Pwm.h" +#include "MotorConfig.h" +#include "commondef.h" +#include "dailex.hpp" + + +struct MotorPorts +{ + int reset; + int enable; + int dir; + int pwm; +}; + +extern const MotorPorts motorPorts_Zouzhi; +extern const MotorPorts motorPorts_Cuozhi; + +class Motor +{ +public: + Motor(MotorPorts motorPorts); + virtual ~Motor(); +protected: + Gpio powerpin; + Gpio resetPin; + //Gpio sleepPin; + Gpio enablePin; + Gpio dirPin; + //Gpio homePin; + //Gpio faultPin; + + Pwm pwm; + + MotorConfig::MTBDType m_mttype; + void start(std::vector& delay_s, const MotorSpeedParam& msp) + { + if (!delay_s.empty()) { + std::vector::iterator iter = delay_s.begin(); + enablePin.setValue(Gpio::Low); + pwm.setFreq(PWM_PERIOD / (*iter)); + pwm.enable(true); + std::this_thread::sleep_for(std::chrono::microseconds((int)msp.finalDelay)); + while (++iter != delay_s.end()) { + pwm.setFreq(PWM_PERIOD / (*iter)); + std::this_thread::sleep_for(std::chrono::microseconds((int)msp.finalDelay)); + } + } + pwm.setFreq(PWM_PERIOD / msp.finalPeriod); + } + +public: + virtual void start(); + + void stop(); + + void pause(); + + void setDirection(int dir); + + void setSpeed(int value); + + static void enablePower(bool bEnable); + +}; +extern std::vector speedup_cfg(int finalPeriod, int Fmin, int stepnum, int a, int offset, int finalDelay); + + diff --git a/device/gxx-linux/motor_run/MotorConfig.cpp b/device/gxx-linux/motor_run/MotorConfig.cpp new file mode 100644 index 0000000..102d038 --- /dev/null +++ b/device/gxx-linux/motor_run/MotorConfig.cpp @@ -0,0 +1,195 @@ +#include "MotorConfig.h" +#include +#include +#include +#include + +using namespace std; +MotorConfig::MotorConfig() +{ + initconfigfile(); +} + +MotorConfig::~MotorConfig() +{ +} + +std::string MotorConfig::GetParams(bool bzouzhi, MTBDType mttype) +{ + std::string j_str; + json j; + if (mttype == MTBDType::MT_TMC) + { + std::ifstream i(bzouzhi ? MT_TMC216_ZOU_PATH : MT_TMC216_CUO_PATH); + i >> j; + j_str = j.dump(); + } + else + { + std::ifstream i(bzouzhi ? MT_DRV888_ZOU_PATH : MT_DRV888_CUO_PATH); + i >> j; + j_str = j.dump(); + } + return j_str; +} + +void MotorConfig::SetParams(bool bzouzhi, MTBDType mttype, MotorSpeedParamEx ¶m) +{ + std::string path; + auto params = GetMotorSpeedParams(bzouzhi, mttype); + for (int i = 0; i < params.size(); i++) + { + if (params[i].dpi == param.dpi && + params[i].colormode == param.colormode && + params[i].speed == param.speed) + { + params[i] = param; + } + } + + json j = json::array(); + + for (int i = 0; i < params.size(); i++) + { + json t_j; + to_json(params[i], t_j); + j.push_back(t_j); + } + + if (mttype == MTBDType::MT_TMC) + path = bzouzhi?MT_TMC216_ZOU_PATH:MT_TMC216_CUO_PATH; + else + path = bzouzhi?MT_DRV888_ZOU_PATH:MT_DRV888_CUO_PATH; + + ofstream ofs(path); + ofs << std::setw(4) << j << std::endl; +} + +std::vector MotorConfig::GetMotorSpeedParams(bool bzouzhi, MTBDType mttype) +{ + std::vector ret; + if (mttype == MTBDType::MT_TMC) + { + std::ifstream i(bzouzhi ? MT_TMC216_ZOU_PATH : MT_TMC216_CUO_PATH); + json j; + i >> j; + for (json::iterator it = j.begin(); it != j.end(); ++it) + { + auto tmv = it.value(); + MotorSpeedParamEx param; + from_json(tmv, param); + ret.push_back(param); + } + } + else + { + std::ifstream i(bzouzhi ? MT_DRV888_ZOU_PATH : MT_DRV888_CUO_PATH); + json j; + i >> j; + for (json::iterator it = j.begin(); it != j.end(); ++it) + { + auto tmv = it.value(); + MotorSpeedParamEx param; + from_json(tmv, param); + ret.push_back(param); + } + } + return ret; +} + +void MotorConfig::initconfigfile() +{ + struct stat buff; + for (int s = 0; s < m_jsonpaths.size(); s++) + { + if (stat(m_jsonpaths[s].c_str(), &buff) != 0) //不存在 + { + { + json j = json::array(); + for (int i = 1; i < 6; i++) + { + MotorSpeedParamEx param; + for (int k = 1; k < 4; k++) + { + // //float ratio = k == 1 ? 1 : (k == 2 ? 1.51 : 2.81); + // param.mt_param.finalPeriod = s >= 2 ? 586500 / 4 : 586500; // s < 2 drv888 + // //param.mt_param.finalPeriod = s >= 2 ? 2000 / 4 : 2000; // s < 2 drv888 + // param.mt_param.Fmin = s >= 2 ? 1607750 / 4 : 1607750; + // param.mt_param.stepnum = 30; + // param.mt_param.a = 200; + // param.mt_param.offset = 7; + // param.mt_param.finalDelay = 2500; + // param.mt_param.acceleration_time = 2; + // param.speed = i; // 0 gray 1 color + // param.dpi = k; // 1 200dpi 2 300dpi 3 600dpi + // param.sp = 1200; + for(int t = 0;t<2;t++) + { + //param.colormode = t; + param = m_motor_params[s*30+(i-1)*6+(k-1)*2+t]; + json t_j; + to_json(param, t_j); + j.push_back(t_j); + } + } + } + ofstream ofs(m_jsonpaths[s]); + ofs << std::setw(4) << j << std::endl; + } + } + } +} + +void MotorConfig::reset_json(){ + // for(int i =0;i MotorConfig::GetMotorSpeedParams(const std::string& json_str) +{ + std::vector ret; + if(json_str.length()) + { + json j = json::parse(json_str); + for (json::iterator it = j.begin(); it != j.end(); ++it) + { + auto tmv = it.value(); + MotorSpeedParamEx param; + from_json(tmv, param); + ret.push_back(param); + } + + } + return ret; +} + +void MotorConfig::to_json(MotorSpeedParamEx ¶m, json &j) +{ + j = json{ + {"A", param.mt_param.a}, + {"FINALDELAY", param.mt_param.finalDelay}, + {"FINALPERIOD", param.mt_param.finalPeriod}, + {"FMIN", param.mt_param.Fmin}, + {"OFFSET", param.mt_param.offset}, + {"STEPNUM", param.mt_param.stepnum}, + {"DPI", param.dpi}, + {"COLORMODE", param.colormode}, + {"ACCELERATIONTIME",param.mt_param.acceleration_time}, + {"SPEED", param.speed}, + {"SP",param.sp}}; +} + +void MotorConfig::from_json(json &j, MotorSpeedParamEx ¶m) +{ + j.at("A").get_to(param.mt_param.a); + j.at("FINALDELAY").get_to(param.mt_param.finalDelay); + j.at("FINALPERIOD").get_to(param.mt_param.finalPeriod); + j.at("FMIN").get_to(param.mt_param.Fmin); + j.at("OFFSET").get_to(param.mt_param.offset); + j.at("STEPNUM").get_to(param.mt_param.stepnum); + j.at("DPI").get_to(param.dpi); + j.at("ACCELERATIONTIME").get_to(param.mt_param.acceleration_time); + j.at("COLORMODE").get_to(param.colormode); + j.at("SPEED").get_to(param.speed), + j.at("SP").get_to(param.sp); +} \ No newline at end of file diff --git a/device/gxx-linux/motor_run/MotorConfig.h b/device/gxx-linux/motor_run/MotorConfig.h new file mode 100644 index 0000000..bf0f96d --- /dev/null +++ b/device/gxx-linux/motor_run/MotorConfig.h @@ -0,0 +1,367 @@ +#pragma once +#include +#include "json.hpp" +#include +#include + +using json= nlohmann::json; + +struct MotorSpeedParam +{ + int finalPeriod; + int Fmin; + float stepnum; + float a; + float offset; + float finalDelay; + float acceleration_time; +}; + +struct MotorSpeedParamEx +{ + MotorSpeedParam mt_param; + int speed; + int colormode; + int dpi; + int sp; +}; + + + + +#ifndef WIN32 +#define MT_DRV888_CUO_PATH "/usr/local/huago/drv888_cuo.json" +#define MT_DRV888_ZOU_PATH "/usr/local/huago/drv888_zou.json" +#define MT_TMC216_CUO_PATH "/usr/local/huago/tmc216_cuo.json" +#define MT_TMC216_ZOU_PATH "/usr/local/huago/tmc216_zou.json" +#else +#define MT_DRV888_CUO_PATH "drv888_cuo.json" +#define MT_DRV888_ZOU_PATH "drv888_zou.json" +#define MT_TMC216_CUO_PATH "tmc216_cuo.json" +#define MT_TMC216_ZOU_PATH "tmc216_zou.json" +#endif +#ifdef G300 + +static std::vector m_motor_params{ + //drv_888 + {{.finalPeriod = 754200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 5910},//40 ppm 搓纸 + {{.finalPeriod = 754200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 1970}, + {{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 3942}, + {{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1314}, + {{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 3942}, + {{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1314}, + + {{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 4509},//50 ppm 搓纸 + {{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1503}, + {{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 3009}, + {{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1003}, + {{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 3009}, + {{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1003}, + + {{.finalPeriod = 656200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 3702},//60 ppm 搓纸 + {{.finalPeriod = 656200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1234}, + {{.finalPeriod = 656300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 2446}, + {{.finalPeriod = 656300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 822}, + {{.finalPeriod = 656300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 2446}, + {{.finalPeriod = 656300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 822}, + + {{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3129},//70 ppm 搓纸 + {{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1043}, + {{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2446}, + {{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 859}, + {{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 2446}, + {{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 859}, + + {{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3129},//80 ppm 搓纸 + {{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1043}, + {{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2446}, + {{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 859}, + {{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 2446}, + {{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 859}, + + {{.finalPeriod = 504200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 5910},//40 ppm 走纸 + {{.finalPeriod = 504200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 1970}, + {{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 3942}, + {{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1314}, + {{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 3942}, + {{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1314}, + + {{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 4509},//50 ppm 走纸 + {{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1503}, + {{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 3009}, + {{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1003}, + {{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 3009}, + {{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1003}, + + {{.finalPeriod = 316200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 3702},//60 ppm 走纸 + {{.finalPeriod = 316200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1234}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 2466}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 822}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 2466}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 822}, + + {{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3129},//70 ppm 走纸 + {{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1043}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2466}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 822}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 2466}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 822}, + + {{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3129},//80 ppm 走纸 + {{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1043}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2466}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 822}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 2466}, + {{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 822}, + + //tmc + {{.finalPeriod = 184200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 5814},//40 ppm 搓纸 + {{.finalPeriod = 184200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 1938}, + {{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 3879}, + {{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1293}, + {{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 3879}, + {{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1293}, + + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 4455},//50 ppm 搓纸 + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1485}, + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 2975}, + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 991}, + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 2972}, + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 991}, + + {{.finalPeriod = 166200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 3570},//60 ppm 搓纸 + {{.finalPeriod = 166200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1190}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 2445}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 815}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 2445}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 815}, + + {{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3126},//70 ppm 搓纸 + {{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1042}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2445}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 815}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 2445}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 815}, + + {{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3126},//80 ppm 搓纸 + {{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1042}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2445}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 815}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 2445}, + {{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 815}, + + {{.finalPeriod = 124200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 5814},//40 ppm 走纸 + {{.finalPeriod = 124200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 1938}, + {{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 3879}, + {{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1293}, + {{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 3879}, + {{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1293}, + + {{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 4455},//50 ppm 走纸 + {{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1485}, + {{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 2975}, + {{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 991}, + {{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 2975}, + {{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 991}, + + {{.finalPeriod = 76200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 3570},//60 ppm 走纸 + {{.finalPeriod = 76200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1190}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 2445}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 815}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 2445}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 815}, + + {{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3126},//70 ppm 走纸 + {{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1042}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2445}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 815}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 2445}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 815}, + + {{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3126},//80 ppm 走纸 + {{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1042}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2445}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 815}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 2445}, + {{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 815}, +}; +#else + +static std::vector m_motor_params{ + //drv_888 + {{.finalPeriod = 754200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 7290},//40 ppm 搓纸 + {{.finalPeriod = 754200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 2430}, + {{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 4869}, + {{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1623}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1583}, + + {{.finalPeriod = 735200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 5870},//50 ppm 搓纸 + {{.finalPeriod = 735200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1950}, + {{.finalPeriod = 735300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 3909}, + {{.finalPeriod = 735300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1303}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1583}, + + {{.finalPeriod = 686200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 5004},//60 ppm 搓纸 + {{.finalPeriod = 686200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1688}, + {{.finalPeriod = 706300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 3248}, + {{.finalPeriod = 706300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 1080}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 1583}, + + {{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3864},//70 ppm 搓纸 + {{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1287}, + {{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2580}, + {{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 859}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 1583}, + + {{.finalPeriod = 508200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3735},//80 ppm 搓纸 + {{.finalPeriod = 508200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1245}, + {{.finalPeriod = 508200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2490}, + {{.finalPeriod = 508200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 830}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 1583}, + + {{.finalPeriod = 504200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 7290},//40 ppm 走纸 + {{.finalPeriod = 504200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 2430}, + {{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 4869}, + {{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1623}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1583}, + + {{.finalPeriod = 385200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 6050},//50 ppm 走纸 + {{.finalPeriod = 405200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1950}, + {{.finalPeriod = 405300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 3909}, + {{.finalPeriod = 405300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1303}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1583}, + + {{.finalPeriod = 346200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 5004},//60 ppm 走纸 + {{.finalPeriod = 346200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1688}, + {{.finalPeriod = 336300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 3248}, + {{.finalPeriod = 336300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 1080}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 1583}, + + {{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3864},//70 ppm 走纸 + {{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1287}, + {{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2580}, + {{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 859}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 1583}, + + {{.finalPeriod = 258200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3735},//80 ppm 走纸 + {{.finalPeriod = 258200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1245}, + {{.finalPeriod = 258200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2490}, + {{.finalPeriod = 258200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 830}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 4749}, + {{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 1583}, + + //tmc + {{.finalPeriod = 184200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 7200},//40 ppm 搓纸 + {{.finalPeriod = 184200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 2400}, + {{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 4800}, + {{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1598}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1586}, + + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 6050},//50 ppm 搓纸 + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 2026}, + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 4053}, + {{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1350}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1586}, + + {{.finalPeriod = 176200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 4978},//60 ppm 搓纸 + {{.finalPeriod = 176200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1659}, + {{.finalPeriod = 176300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 3330}, + {{.finalPeriod = 176300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 1110}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 1586}, + + {{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3858},//70 ppm 搓纸 + {{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1286}, + {{.finalPeriod = 137300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2570}, + {{.finalPeriod = 137300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 857}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 1586}, + + {{.finalPeriod = 128200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3750},//80 ppm 搓纸 + {{.finalPeriod = 128200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1250}, + {{.finalPeriod = 128300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2498}, + {{.finalPeriod = 128300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 832}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 1586}, + + {{.finalPeriod = 124200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 7200},//40 ppm 走纸 + {{.finalPeriod = 124200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 2400}, + {{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 4800}, + {{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1598}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1586}, + + {{.finalPeriod = 105200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 6050},//50 ppm 走纸 + {{.finalPeriod = 105200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 2026}, + {{.finalPeriod = 105200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 4053}, + {{.finalPeriod = 105200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1350}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1586}, + + {{.finalPeriod = 86200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 4978},//60 ppm 走纸 + {{.finalPeriod = 86200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1659}, + {{.finalPeriod = 86300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 3330}, + {{.finalPeriod = 86300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 1110}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 1586}, + + {{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3858},//70 ppm 走纸 + {{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1286}, + {{.finalPeriod = 66730, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2572}, + {{.finalPeriod = 66730, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 857}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 1586}, + + {{.finalPeriod = 64820, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3750},//80 ppm 走纸 + {{.finalPeriod = 64820, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1250}, + {{.finalPeriod = 64830, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2498}, + {{.finalPeriod = 64830, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 832}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 4760}, + {{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 1586}, +}; +#endif + + +class MotorConfig +{ +private: + std::vector m_cuoParams; + std::vector m_zouParams; + const std::vector m_jsonpaths={ + MT_DRV888_CUO_PATH, + MT_DRV888_ZOU_PATH, + MT_TMC216_CUO_PATH, + MT_TMC216_ZOU_PATH + }; + +public: + enum class MTBDType + { + MT_TMC, + MT_DRV + }; + MotorConfig(/* args */); + ~MotorConfig(); + std::string GetParams(bool bzouzhi,MTBDType mttype); + void SetParams(bool bzouzhi,MTBDType mttype,MotorSpeedParamEx& param); + std::vector GetMotorSpeedParams(bool bzouzhi,MTBDType mttype); + std::vector GetMotorSpeedParams(const std::string& json_str); + void to_json(MotorSpeedParamEx& param,json& j); + void from_json(json& j,MotorSpeedParamEx& param); + void reset_json(); +private: + void initconfigfile(); + +}; + diff --git a/device/gxx-linux/motor_run/MotorControl.cpp b/device/gxx-linux/motor_run/MotorControl.cpp new file mode 100644 index 0000000..42b9dfc --- /dev/null +++ b/device/gxx-linux/motor_run/MotorControl.cpp @@ -0,0 +1,60 @@ +#pragma once + +#include "CuoZhiMotor.h" +#include "ZouZhiMotor.h" +#include "MotorControl.h" + +MotorControl::MotorControl() +{ + m_zzm.reset(new ZouZhiMotor()); + m_czm.reset(new CuoZhiMotor()); + //m_czm->reset(); +} +MotorControl::~MotorControl() +{ + m_zzm->stop(); + m_czm->stop(); + m_czm.reset(); + m_zzm.reset(); +} +void MotorControl::MotorRun(MotorOption option) +{ + switch (option) + { + case MotorOption::CZ_Reset : + m_czm->reset(); + break; + case MotorOption::CZ_Forward : + m_czm->forward(); + break; + case MotorOption::CZ_Backward : + m_czm->backward(); + break; + case MotorOption::CZ_Pause: + m_czm->pause(); + break; + case MotorOption::CZ_Stop : + m_czm->stop(); + break; + case MotorOption::ZZ_Backward : + m_zzm->setDirection(1); + m_zzm->start(); + break; + case MotorOption::ZZ_Forward : + m_zzm->setDirection(0); + m_zzm->start(); + break; + case MotorOption::ZZ_Stop : + m_zzm->stop(); + break; + default: + break; + } +} + +void MotorControl::setzzspeed(int zuo_spmode,int dpi,int iscolor){ + m_zzm->speedChange(zuo_spmode,dpi,iscolor); +} +void MotorControl::setczspeed(int cuo_spmode,int dpi,int iscolor){ + m_czm->speedChange(cuo_spmode,dpi,iscolor); +} diff --git a/device/gxx-linux/motor_run/MotorControl.h b/device/gxx-linux/motor_run/MotorControl.h new file mode 100644 index 0000000..9111b90 --- /dev/null +++ b/device/gxx-linux/motor_run/MotorControl.h @@ -0,0 +1,28 @@ +#pragma once +class CuoZhiMotor; +class ZouZhiMotor; +struct MotorSpeedParam; + + +class MotorControl +{ +public: + enum MotorOption : int{ + CZ_Reset, + CZ_Forward, + CZ_Backward, + CZ_Pause, + CZ_Stop, + ZZ_Forward, + ZZ_Backward, + ZZ_Stop, + }; + MotorControl(); + ~MotorControl(); + void setzzspeed(int zuo_spmode,int dpi,int iscolor); + void setczspeed(int cuo_spmode,int dpi,int iscolor); + void MotorRun(MotorOption option); +private: + std::unique_ptr m_czm; + std::unique_ptr m_zzm; +}; diff --git a/device/gxx-linux/motor_run/Pwm.cpp b/device/gxx-linux/motor_run/Pwm.cpp new file mode 100644 index 0000000..2125069 --- /dev/null +++ b/device/gxx-linux/motor_run/Pwm.cpp @@ -0,0 +1,40 @@ +#include "Pwm.h" +#include "DevUtil.h" +#include + +#define PWMPATH "%s%d/pwm0/%s" + +Pwm::Pwm(int port) +{ + path_enable = string_format(PWMPATH, path_base.c_str(), port, path_enable.c_str()); + path_duty_cycle = string_format(PWMPATH, path_base.c_str(), port, path_duty_cycle.c_str()); + path_period = string_format(PWMPATH, path_base.c_str(), port, path_period.c_str()); + printf("Pwm::Pwm(int port = %d)\n",port); +} + +Pwm::~Pwm() +{ + std::cout << "Pwm::~Pwm()" << std::endl; +} + +void Pwm::setFreq(int freq) +{ + int value = PWM_PERIOD / freq; + write_dev(path_period, value); + write_dev(path_duty_cycle, value / 2); +} + +int Pwm::getFreq() +{ + return PWM_PERIOD/read_dev_i(path_period); +} + +void Pwm::enable(bool bEnable) +{ + write_dev(path_enable, bEnable); +} + +bool Pwm::isEnable() +{ + return (bool)read_dev_i(path_enable); +} diff --git a/device/gxx-linux/motor_run/Pwm.h b/device/gxx-linux/motor_run/Pwm.h new file mode 100644 index 0000000..c31bfbf --- /dev/null +++ b/device/gxx-linux/motor_run/Pwm.h @@ -0,0 +1,22 @@ +#pragma once +#include +#define PWM_PERIOD 1000000000 + +class Pwm +{ +public: + Pwm(int port); + ~Pwm(); + + void setFreq(int freq); + int getFreq(); + + void enable(bool bEnable); + bool isEnable(); + +private: + const std::string path_base = "/sys/class/pwm/pwmchip"; + std::string path_enable = "enable"; + std::string path_duty_cycle = "duty_cycle"; + std::string path_period = "period"; +}; \ No newline at end of file diff --git a/device/gxx-linux/motor_run/ZouZhiMotor.cpp b/device/gxx-linux/motor_run/ZouZhiMotor.cpp new file mode 100644 index 0000000..c497615 --- /dev/null +++ b/device/gxx-linux/motor_run/ZouZhiMotor.cpp @@ -0,0 +1,48 @@ +#include "ZouZhiMotor.h" +#include +#include + +ZouZhiMotor::ZouZhiMotor() : Motor(motorPorts_Zouzhi) +{ + speedChange(0,1,1); + if(Dail().GetValue().dails.in_voltage4 == 0) + m_mttype = MotorConfig::MTBDType::MT_DRV; + else + m_mttype = MotorConfig::MTBDType::MT_TMC; +} + +ZouZhiMotor::~ZouZhiMotor() +{ + std::cout << "ZouZhiMotor::~ZouZhiMotor()" << std::endl; +} + +void ZouZhiMotor::start() +{ + Motor::start(delays, mspZhouzhi); +} + +void ZouZhiMotor::speedChange(int speed,int dpi ,int iscolor) +{ + // if(zouZhiFinalDelay.find(dpi)==zouZhiFinalDelay.end()) + // dpi = 1; + // m_speedmode = speed; + // printf(" \n speed %d",speed); + // mspZhouzhi = { .finalPeriod = zouZhiFinalPeriod.at(dpi)[m_speedmode],.Fmin = zouZhiFmin.at(dpi)[m_speedmode],.stepnum = zouZhiStepNum.at(dpi)[m_speedmode],.a = zouZhiA.at(dpi)[m_speedmode], + // .offset = zouZhiOffset.at(dpi)[m_speedmode],.finalDelay = zouZhiFinalDelay.at(dpi)[m_speedmode] }; + // std::cout<< ".finalPeriod = "< delays; + MotorSpeedParam mspZhouzhi; + MotorConfig m_cfg; + int m_speedmode; + + const std::map> zouZhiFinalPeriod ={ + {1,{ 586500,420500,330000,245000,205000 }}, + {2,{ 916500,656500,530500,386500,347000 }}, + {3,{ 756500,756500,756500,756500,756500 }}, + };//756500,556500,426500,336500,286500,230500 //265000 + const std::map> zouZhiFmin ={ + {1,{ 1607750,1607750,1607750,1607750,1607750 }}, + {2,{ 1607750,1607750,1607750,1607750,1607750 }}, + {3,{ 1607750,1607750,1607750,1607750,1607750 }}, + };//1607750,1607750,1607750,1607750,1607750,1607750 + const std::map> zouZhiStepNum ={ + { 1, { 23,23,30,30,30 }}, + { 2, { 30,30,30,30,30 }}, + { 3, { 30,30,30,30,30 }}, + }; + const std::map> zouZhiA = { + {1,{ 200,200,200,200,200 }}, + {2,{ 200,200,200,200,200 }}, + {3,{ 200,200,200,200,200 }}, + }; + const std::map> zouZhiOffset = { + {1,{ 7,7,7,7,9 }}, + {2,{ 7,7,7,7,7 }}, + {3,{ 7,7,7,7,7 }}, + }; + const std::map> zouZhiFinalDelay = { + {1,{ 2500,2500,2500,2500,2500 }}, + {2,{ 2500,2500,2500,2500,2500 }}, + {3,{ 2500,2500,2500,2500,2500 }}, + }; +}; + + + diff --git a/device/gxx-linux/motor_run/main.cpp b/device/gxx-linux/motor_run/main.cpp new file mode 100644 index 0000000..4bb4863 --- /dev/null +++ b/device/gxx-linux/motor_run/main.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include +#include "DevUtil.h" +#include "Pwm.h" +#include "ZouZhiMotor.h" +#include "CuoZhiMotor.h" + + +int main(int argc,char **argv) { + + //DeviceExport(); /*类里面的构造函数可以直接调用*/ + DeviceExport d1; + ZouZhiMotor zzm; + CuoZhiMotor czm; + std::string instring; + do { + printf("1.cuozhi motor reset\n"); + printf("2.cuozhi motor forward\n"); + printf("3.cuozhi motor reverse\n"); + printf("4.cuozhi motor stop\n"); + printf("5.zouzhi motor forward\n"); + printf("6.zouzhi motor reverse\n"); + printf("7.zouzhi motor stop\n"); + printf(":"); + std::getline(std::cin, instring); + if (instring == "1") { + czm.reset(); + } + if (instring == "2") { + czm.forward(); + } + if (instring == "3") { + czm.backward(); + } + if (instring == "4") { + czm.stop(); + } + if (instring == "5") { + zzm.setDirection(0); + zzm.start(); + } + if (instring == "6") { + zzm.setDirection(1); + zzm.start(); + } + if (instring == "7") { + zzm.stop(); + } + }while(1); + return 0; +} diff --git a/device/gxx-linux/motor_run/xmake.lua b/device/gxx-linux/motor_run/xmake.lua new file mode 100644 index 0000000..68a3eeb --- /dev/null +++ b/device/gxx-linux/motor_run/xmake.lua @@ -0,0 +1,89 @@ +add_rules("mode.debug", "mode.release") + +target("motor_run") + set_kind("static") + add_files("Motor.cpp") + add_files("DevUtil.cpp") + add_files("ZouZhiMotor.cpp") + add_files("CuoZhiMotor.cpp") + add_files("Gpio.cpp") + add_files("Pwm.cpp") + add_files("MotorControl.cpp") + add_files("MotorConfig.cpp") + add_includedirs(".", { public = true}) + add_includedirs("../packages/common.pkg/include", { public = true}) + --add_packages("common") +target("main") + set_kind("binary") + add_files("main.cpp") + add_deps("motor_run") + +-- +-- If you want to known more usage about xmake, please see https://xmake.io +-- +-- ## FAQ +-- +-- You can enter the project directory firstly before building project. +-- +-- $ cd projectdir +-- +-- 1. How to build project? +-- +-- $ xmake +-- +-- 2. How to configure project? +-- +-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release] +-- +-- 3. Where is the build output directory? +-- +-- The default output directory is `./build` and you can configure the output directory. +-- +-- $ xmake f -o outputdir +-- $ xmake +-- +-- 4. How to run and debug target after building project? +-- +-- $ xmake run [targetname] +-- $ xmake run -d [targetname] +-- +-- 5. How to install target to the system directory or other output directory? +-- +-- $ xmake install +-- $ xmake install -o installdir +-- +-- 6. Add some frequently-used compilation flags in xmake.lua +-- +-- @code +-- -- add debug and release modes +-- add_rules("mode.debug", "mode.release") +-- +-- -- add macro defination +-- add_defines("NDEBUG", "_GNU_SOURCE=1") +-- +-- -- set warning all as error +-- set_warnings("all", "error") +-- +-- -- set language: c99, c++11 +-- set_languages("c99", "c++11") +-- +-- -- set optimization: none, faster, fastest, smallest +-- set_optimize("fastest") +-- +-- -- add include search directories +-- add_includedirs("/usr/include", "/usr/local/include") +-- +-- -- add link libraries and search directories +-- add_links("tbox") +-- add_linkdirs("/usr/local/lib", "/usr/lib") +-- +-- -- add system link libraries +-- add_syslinks("z", "pthread") +-- +-- -- add compilation and link flags +-- add_cxflags("-stdnolib", "-fno-strict-aliasing") +-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true}) +-- +-- @endcode +-- + diff --git a/device/gxx-linux/motorboard/Imotorboard.cpp b/device/gxx-linux/motorboard/Imotorboard.cpp new file mode 100644 index 0000000..134f59c --- /dev/null +++ b/device/gxx-linux/motorboard/Imotorboard.cpp @@ -0,0 +1,16 @@ +#include +#include "Imotorboard.h" +#include "PinMonitor.h" +#include "uartregsaccess.h" +#include +#include "stringex.hpp" +#include "config.h" +#include "StopWatch.h" +#include "applog.h" +#include "Capturer.h" + +IMotorBoard::IMotorBoard() : mb_ev_cb_(std::function()) +{} +IMotorBoard::~IMotorBoard(){ + +} diff --git a/device/gxx-linux/motorboard/Imotorboard.h b/device/gxx-linux/motorboard/Imotorboard.h new file mode 100644 index 0000000..bf3b4fe --- /dev/null +++ b/device/gxx-linux/motorboard/Imotorboard.h @@ -0,0 +1,98 @@ +#pragma once +#include +#include +#include +#include +#include "autoevent.hpp" +#include "commondef.h" +#include "Led.h" +#include "StopWatch.h" +#include "ThreadPool.h" + +class IRegsAccess; +class PinMonitor; +class Gpio; +class ICapturer; + +#include "../usb/src/common/packet.h" + + +class IMotorBoard{ +public: + IMotorBoard(); + virtual ~IMotorBoard(); + virtual void start() = 0; + virtual void stop() = 0; + virtual void clear_error() = 0; + virtual void pick_paper() = 0; + virtual void stop_pick_paper() = 0; + virtual int os_mode() = 0; + virtual bool paper_ready() = 0; + virtual bool is_converopen() = 0; + virtual bool is_scanning() = 0; + virtual bool is_jam() = 0; + virtual int paper_counter() = 0; + virtual bool set_long_paper(bool enable) = 0; + virtual bool set_double_inpect(bool enable) = 0; + virtual bool set_staple_inpect(bool enable) = 0; + virtual bool set_auto_paper(bool enable) = 0; + virtual bool set_color_mode(int mode) = 0; + virtual int get_speed_mode() = 0; + virtual bool set_speed_mode(int mode,int dpi,int iscolor) = 0; + virtual bool set_screw_inpect(bool enable) = 0; + virtual bool get_screw_inpect() = 0; + virtual bool set_screw_level(int level) = 0; + virtual int get_screw_level() = 0; + virtual bool wait_paper_out(int timeout_ms) = 0; + virtual bool wait_paper_in(int timeout_ms) = 0; + virtual bool read(unsigned int addr, unsigned int &val) = 0; + virtual bool write(unsigned int addr, unsigned int val) = 0; + virtual bool set_cuospeed(unsigned int speed,uint dpi,uint iscolor) = 0; + virtual void set_callbacks(MotorBoardGlue glue) = 0; + virtual bool get_keeplastpaper() = 0; + virtual std::shared_ptr regs() = 0; + virtual void set_capture(std::shared_ptr cap) = 0; + virtual void motor_reset() = 0; + virtual void LedControlOption(HG_LedOption option,uint32_t time) = 0; + virtual void clean_paper_road() = 0; + + void set_error(int value){ + mb_error = value; + } + void set_scancap(GScanCap cap) + { + m_scancap = cap; + } + void set_motorboard_event_callback(std::function cb) + { + mb_ev_cb_ = cb; + } + + static scanner_status scanner_status_from_raw(int raw) + { + switch(raw) + { + case 1: + return SCANNER_STATUS_PAPER_JAMMED; + case 2: + return SCANNER_STATUS_NO_PAPER; + case 4: + return SCANNER_STATUS_COVER_OPENNED; + case 0x20: + return SCANNER_STATUS_DOUBLE_FEEDED; + case 0x2000000: + return SCANNER_STATUS_PAPER_ON; + case 0x4000000: + return SCANNER_STATUS_COVER_CLOSED; + case 0: + default: + return SCANNER_STATUS_READY; // jam has resolved + } + } + +protected: + volatile int mb_error = 0; + GScanCap m_scancap; + + std::function mb_ev_cb_; +}; \ No newline at end of file diff --git a/device/gxx-linux/motorboard/Led.cpp b/device/gxx-linux/motorboard/Led.cpp new file mode 100644 index 0000000..577fc41 --- /dev/null +++ b/device/gxx-linux/motorboard/Led.cpp @@ -0,0 +1,95 @@ +#include "Led.h" + +#define LEDPATH "%s/%s/%s" + +std::string Led::timer = "timer"; +std::string Led::none = "none"; + +Led::Led(std::string name) { + path_brightness = string_format(LEDPATH, path_base.c_str(), name.c_str(), path_brightness.c_str()); + path_trigger = string_format(LEDPATH, path_base.c_str(), name.c_str(), path_trigger.c_str()); + path_delay_off = string_format(LEDPATH, path_base.c_str(), name.c_str(), path_delay_off.c_str()); + path_delay_on = string_format(LEDPATH, path_base.c_str(), name.c_str(), path_delay_on.c_str()); +} + +Led::~Led() { +} + +void Led::on(int time_ms) { + if (time_ms != 0) { + write_dev(path_trigger, timer); + write_dev(path_delay_off, time_ms); + write_dev(path_delay_on, time_ms); + } else { + //if (read_dev_s(path_trigger).find(none) == std::string::npos) + write_dev(path_trigger, none); + } + write_dev(path_brightness, 1); +} + +void Led::off() { + write_dev(path_brightness, 0); +} + +bool Led::isOn() { + return (bool)read_dev_i(path_brightness); +} + + +LedControl::LedControl():m_led_green(Led("green")),m_led_red(Led("red")),m_led_white(Led("white")){ +} +LedControl::~LedControl(){ + option(HG_LedOption::HG_OFF_ALL,0); +} + +HG_LedOption LedControl::get_state(){ + return m_state; +} +void LedControl::option(HG_LedOption option,uint32_t time){ + m_state = option; + switch (option) + { + case HG_LedOption::HG_OFF_ALL: + m_led_red.off(); + m_led_green.off(); + m_led_white.off(); + break; + case HG_LedOption::HG_ON_ALL: + m_led_green.on(time); + m_led_red.on(time); + m_led_white.on(time); + break; + case HG_LedOption::HG_RED_ON: + m_led_red.on(time); + m_led_green.off(); + m_led_white.off(); + break; + case HG_LedOption::HG_GREEN_ON: + m_led_green.on(time); + m_led_red.off(); + m_led_white.off(); + break; + case HG_LedOption::HG_WHITE_ON: + m_led_red.off(); + m_led_green.off(); + m_led_white.on(time); + break; + case HG_LedOption::HG_RED_WHITR_ON: + m_led_green.off(); + m_led_red.on(time); + m_led_white.on(time); + break; + case HG_LedOption::HG_RED_GREEN_ON: + m_led_red.on(time); + m_led_green.on(time); + m_led_white.off(); + break; + case HG_LedOption::HG_GREEN_WHITR_ON: + m_led_green.on(time); + m_led_red.off(); + m_led_white.on(time); + break; + default: + break; + } +} diff --git a/device/gxx-linux/motorboard/Led.h b/device/gxx-linux/motorboard/Led.h new file mode 100644 index 0000000..054ca82 --- /dev/null +++ b/device/gxx-linux/motorboard/Led.h @@ -0,0 +1,50 @@ +#pragma once +#include "DevUtil.h" +#include "stringex.hpp" + +enum HG_LedOption : uint8_t{ + HG_OFF_ALL = 0, + HG_RED_ON, + HG_GREEN_ON, + HG_WHITE_ON, + HG_RED_GREEN_ON, + HG_RED_WHITR_ON, + HG_GREEN_WHITR_ON, + HG_ON_ALL, +}; + +class Led +{ +public: + static std::string timer; + static std::string none; +public: + Led(std::string name); + ~Led(); + + void on(int time_ms = 0); + void off(); + bool isOn(); + +private: + const std::string path_base = "/sys/class/leds"; + std::string path_brightness = "brightness"; + std::string path_trigger = "trigger"; + std::string path_delay_off = "delay_off"; + std::string path_delay_on = "delay_on"; +}; + +class LedControl{ +public: + + LedControl(); + ~LedControl(); + void option(HG_LedOption option,uint32_t time = 0); + HG_LedOption get_state(); + +private: + Led m_led_red; + Led m_led_green; + Led m_led_white; + HG_LedOption m_state; +}; diff --git a/device/gxx-linux/motorboard/motorboard.cpp b/device/gxx-linux/motorboard/motorboard.cpp index 58b590b..1c6cb0f 100644 --- a/device/gxx-linux/motorboard/motorboard.cpp +++ b/device/gxx-linux/motorboard/motorboard.cpp @@ -8,7 +8,6 @@ #include "StopWatch.h" #include "applog.h" #include "Capturer.h" - static const std::string loggername = "MotorBoard"; @@ -87,15 +86,6 @@ bool MotorBoard::wait_paper_out(int timeout_ms) return cv_paper_out.wait(timeout_ms); } -bool MotorBoard::wait_error(int timeout_ms) -{ - return cv_error.wait(timeout_ms); -} - -bool MotorBoard::wait_done(int timeout_ms) -{ - return cv_scan_done.wait(timeout_ms); -} int MotorBoard::os_mode() { @@ -112,7 +102,13 @@ bool MotorBoard::paper_ready() SMB_MODE *smb_mode = (SMB_MODE *)&val; return smb_mode->feeding_paper_ready; } - +bool MotorBoard::is_converopen() +{ + unsigned int val; + read(0x02, val); + SMBSTATUS *smb_mode = (SMBSTATUS *)&val; + return smb_mode->open_machine; +} bool MotorBoard::is_scanning() { unsigned int val; @@ -121,6 +117,31 @@ bool MotorBoard::is_scanning() return smb_mode->work_status; } +bool MotorBoard::is_jam() +{ + return false; +} + +void MotorBoard::motor_reset(){ +} + +void MotorBoard::clean_paper_road() +{ + unsigned int val; + SMB_FUNC *smbc = (SMB_FUNC *)(&val); + read(6, val); + if(smbc->param.work_mode == 0) + { + smbc->param.func_clean_passthro = 1; + write(6, val); + smbc->param.func_clean_passthro = 0; + write(6, val); + } + else{ + printf("\n 非空闲模式不允许清理纸道!!!!"); + } +} + int MotorBoard::paper_counter() { unsigned int val; @@ -129,39 +150,11 @@ int MotorBoard::paper_counter() return smb_mode->scan_num; } -bool MotorBoard::set_paper_inspect_param(unsigned int value /* = 1000 */) -{ - unsigned int val; - if (!read(0x04, val)) - return false; - SMBCONFIGEXT *smb_config_ext = (SMBCONFIGEXT *)&val; - smb_config_ext->error_range_set = value; - return write(0x04, val); -} bool MotorBoard::get_keeplastpaper(){ return keep_last_paper; } -bool MotorBoard::set_paper_inpect_info(unsigned int value) -{ - unsigned int val; - if (!read(0x04, val)) - return false; - SMBCONFIGEXT *smb_config_ext = (SMBCONFIGEXT *)&val; - smb_config_ext->paper_infor = value; - return write(0x04, val); -} - -bool MotorBoard::set_paper_inspect(bool enable /* = true */) -{ - unsigned int val; - if (!read(0x04, val)) - return false; - SMBCONFIGEXT *smb_config_ext = (SMBCONFIGEXT *)&val; - smb_config_ext->paper_size_check_en = enable; - return write(0x04, val); -} bool MotorBoard::set_double_inpect(bool enable) { @@ -172,16 +165,13 @@ bool MotorBoard::set_double_inpect(bool enable) smb_config->double_paper = enable; return write(0x00, val); } -bool MotorBoard::get_doublle_inpect() -{ -} bool MotorBoard::set_auto_paper(bool enable){ unsigned int val; if (!read(0x00, val)) return false; SMBCONFIG *smb_config = (SMBCONFIG *)&val; - smb_config->paper_auto_module = enable; + smb_config->autofeed_mode = enable; return write(0x00, val); } @@ -195,9 +185,7 @@ bool MotorBoard::set_staple_inpect(bool enable) return write(0x00, val); } -bool MotorBoard::get_staple_inpect() -{ -} + bool MotorBoard::set_color_mode(int mode) { unsigned int val; @@ -207,11 +195,8 @@ bool MotorBoard::set_color_mode(int mode) smb_config->color_mode = mode; return write(0x00, val); } -int MotorBoard::get_color_mode() -{ -} -bool MotorBoard::set_speed_mode(int mode) +bool MotorBoard::set_speed_mode(int mode,int dpi,int iscolor) { unsigned int val; if (!read(0x00, val)) @@ -234,7 +219,7 @@ int MotorBoard::get_speed_mode() return smb_config->v_setting; } -bool MotorBoard::set_cuospeed(unsigned int speed) +bool MotorBoard::set_cuospeed(unsigned int speed,uint dpi,uint iscolor) { unsigned int val; if (!read(0x04, val)) @@ -259,7 +244,6 @@ void MotorBoard::pin_call(unsigned int pinNum) if (m_os_mode != os_m) { m_os_mode = os_m; - cv_os_mode.notify_all(); if (m_glue.m_os_mode_call) m_glue.m_os_mode_call(m_os_mode); } @@ -290,14 +274,13 @@ void MotorBoard::pin_call(unsigned int pinNum) if(m_glue.m_mltop_call) m_glue.m_mltop_call(val); } - if(smb_status->paper_auto) + if(smb_status->auto_feed) { if(m_glue.m_auto_paper) m_glue.m_auto_paper(1); } if (val & 0xAFE) { - cv_error.notify_all(); if (m_glue.m_error_call) m_glue.m_error_call(val & 0x30efe); //0xefe index of 16:aquireimage error index of bit 17 :size check error @@ -323,7 +306,6 @@ void MotorBoard::pin_call(unsigned int pinNum) if (val & 0x400) { LOG_TRACE("done"); - cv_scan_done.notify_all(); if (m_glue.m_scan_done_call) m_glue.m_scan_done_call(); } @@ -403,30 +385,3 @@ int MotorBoard::get_screw_level() SMBCONFIG *smb_mode = (SMBCONFIG *)&val; return smb_mode->skew_parameter; } - -bool MotorBoard::en_testbit(bool en) -{ - unsigned int val; - auto ret= read(0x00, val); - if(!ret) - return -1; - SMBCONFIG *smb_mode = (SMBCONFIG *)&val; - smb_mode->testbit = en?1:0; - return write(0x00,val); -} - -void MotorBoard::release_statecontrol() -{ - set_auto_paper(false); - m_regsAccess.reset(); - m_intPinMonitor.reset(); - -} - -void MotorBoard::init_statecontrol() -{ - m_regsAccess.reset(new UartRegsAccess(devPort, bauds, 0x07, 0x87)); - m_intPinMonitor.reset(new PinMonitor(intport, std::bind(&MotorBoard::pin_call, this, std::placeholders::_1))); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - m_os_mode = os_mode(); -} \ No newline at end of file diff --git a/device/gxx-linux/motorboard/motorboard.h b/device/gxx-linux/motorboard/motorboard.h index f8c10fb..87d0def 100644 --- a/device/gxx-linux/motorboard/motorboard.h +++ b/device/gxx-linux/motorboard/motorboard.h @@ -1,15 +1,6 @@ #pragma once -#include -#include -#include -#include -#include "autoevent.hpp" -#include "commondef.h" +#include "Imotorboard.h" -class IRegsAccess; -class PinMonitor; -class Gpio; -class ICapturer; typedef struct SMB_CONFIG { @@ -17,23 +8,23 @@ typedef struct SMB_CONFIG unsigned int color_mode : 1; unsigned int paper : 1; unsigned int double_paper : 1; - unsigned int staple_enable : 1; // 5 + unsigned int staple_enable : 1;//5 unsigned int error_clean : 1; unsigned int status_init : 1; unsigned int pick_paper : 1; unsigned int skew_enable : 1; - unsigned int skew_parameter : 3; // 7 - unsigned int key_staple_enable : 1; + unsigned int skew_parameter : 3; + unsigned int key_staple_enable : 1;//8 unsigned int iic_config_addr : 7; unsigned int iic_config : 1; - unsigned int v_setting : 2; // 11 + unsigned int v_setting : 2;//10 unsigned int speed_set_enable : 1; unsigned int scan_busy_motor_stop : 1; - unsigned int sleep_state : 1; - unsigned int sleep_parameter : 3; // 6 - unsigned int _600dpi : 1; - unsigned int paper_auto_module : 1; // 2 - unsigned int testbit : 1; + unsigned int dpi_mode : 2; + unsigned int sleep_parameter : 2;//6 + unsigned int dpi600:1; + unsigned int autofeed_mode:1; + unsigned int lifter_en:1; } SMBCONFIG; typedef struct SMB_STATUS @@ -54,10 +45,10 @@ typedef struct SMB_STATUS unsigned int sleep_conf : 3; unsigned int dsp_get_paper_error : 1; unsigned int paper_check_result : 1; - unsigned int top_wuzhi : 1; - unsigned int ml_top_sin : 1; // 10 - unsigned int paper_auto : 1; - unsigned int paper_left : 1; + unsigned int arrival_top:1;//������ֽ + unsigned int arrival_top_int:1;//���ﶥ���ж� + unsigned int auto_feed:1;//4 + unsigned int paper_left:1; } SMBSTATUS; typedef struct SMB_MODE @@ -76,50 +67,74 @@ typedef struct SMB_CONFIG_EXT unsigned int cuo_speed : 7; } SMBCONFIGEXT; -class MotorBoard +typedef struct SMB_CONFIG_TIME +{ + unsigned int error_time_set : 7; +} SMBCONFIGTIME; + + +//Reg 6 +typedef union SMB_FUNC +{ + struct{ + unsigned int work_mode : 3; + unsigned int func_clean_passthro : 1; + unsigned int func_feed_low : 1; + unsigned int func_feed_mid : 1; + unsigned int func_feed_high : 1; + unsigned int key_sound : 1; + unsigned int key_endouble_feed : 1; + unsigned int func_encount : 1; + unsigned int func_clear_count : 1; + unsigned int motor_choose : 2; + unsigned int wr_en : 1; + unsigned int motor_addr : 8; + unsigned int key_stop_enable : 1; + unsigned int lift_init_set: 2; + }param; + unsigned int value; +} SMBFUNC; + +class MotorBoard : public IMotorBoard { public: MotorBoard(); - void start(); - void stop(); - void clear_error(); - void pick_paper(); - int os_mode(); - bool paper_ready(); - bool is_scanning(); - int paper_counter(); - bool set_long_paper(bool enable); - bool set_double_inpect(bool enable); - bool get_doublle_inpect(); - bool set_staple_inpect(bool enable); - bool set_auto_paper(bool enable); - bool get_staple_inpect(); - bool set_color_mode(int mode); - int get_color_mode(); - int get_speed_mode(); - bool set_speed_mode(int mode); - bool set_screw_inpect(bool enable); - bool get_screw_inpect(); - bool set_screw_level(int level); - int get_screw_level(); - bool wait_paper_out(int timeout_ms); - bool wait_paper_in(int timeout_ms); - bool wait_error(int timeout_ms); - bool wait_done(int timeout_ms); - bool read(unsigned int addr, unsigned int &val); - bool write(unsigned int addr, unsigned int val); - bool set_paper_inspect_param(unsigned int value = 1000); - bool set_paper_inpect_info(unsigned int value); - bool set_paper_inspect(bool enable = true); - bool set_cuospeed(unsigned int speed); - void set_callbacks(MotorBoardGlue glue); - bool get_keeplastpaper(); - bool en_testbit(bool en); - std::shared_ptr regs(); - void set_capture(std::shared_ptr cap); - void release_statecontrol(); - void init_statecontrol(); + void start() override; + void stop() override; + void clear_error() override; + void pick_paper() override; + void stop_pick_paper() override{}; + int os_mode() override; + bool paper_ready() override; + bool is_scanning() override; + bool is_jam() override; + int paper_counter() override; + bool is_converopen() override; + bool set_long_paper(bool enable) override; + bool set_double_inpect(bool enable) override; + bool set_staple_inpect(bool enable) override; + bool set_auto_paper(bool enable) override; + bool set_color_mode(int mode) override; + int get_speed_mode() override; + bool set_speed_mode(int mode,int dpi,int iscolor) override; + bool set_screw_inpect(bool enable) override; + bool get_screw_inpect() override; + bool set_screw_level(int level) override; + int get_screw_level() override; + bool wait_paper_out(int timeout_ms) override; + bool wait_paper_in(int timeout_ms) override; + bool read(unsigned int addr, unsigned int &val) override; + bool write(unsigned int addr, unsigned int val) override; + bool set_cuospeed(unsigned int speed,uint dpi = 0,uint iscolor = 1) override; + void set_callbacks(MotorBoardGlue glue) override; + bool get_keeplastpaper() override; + std::shared_ptr regs() override; + void set_capture(std::shared_ptr cap) override; + void motor_reset() override; + void LedControlOption(HG_LedOption option,uint32_t time) override{}; + void clean_paper_road() override; + private: void pin_call(unsigned int pinNum); void scansensor_call(unsigned int pinNum); @@ -133,9 +148,6 @@ private: std::shared_ptr m_uartEnable; AutoSemaphore cv_paper_out; AutoSemaphore cv_paper_in; - AutoSemaphore cv_error; - AutoSemaphore cv_scan_done; - AutoSemaphore cv_os_mode; unsigned int m_os_mode; volatile bool keep_last_paper; MotorBoardGlue m_glue; diff --git a/device/gxx-linux/motorboard/motormanager.cpp b/device/gxx-linux/motorboard/motormanager.cpp new file mode 100644 index 0000000..d46d4f7 --- /dev/null +++ b/device/gxx-linux/motorboard/motormanager.cpp @@ -0,0 +1,320 @@ +#include "motormanager.h" +#include "MotorControl.h" +#include "sensormonitor.h" +#include +#include "Led.h" + +MotorManager::MotorManager():m_motorcontrol(new MotorControl()), + m_ledcontrol(new LedControl()), + is_usb_connect(false), + is_sleeping(false), + is_autopaper(false), + is_motor_run(false), + autopaper_state_change(false), + autopaperthread(1), + m_glue({nullptr,nullptr,nullptr,nullptr,nullptr,nullptr}) +{ + GetorSetSysClassValue(false,HG_PWM_FAN,false); + GetorSetSysClassValue(false,HG_MOTOR_FAN,false); + m_sensormonitor.reset(new SensorMonitor([&](int value){pincall(value);})); + m_ledcontrol->option(HG_WHITE_ON,300); +} + +MotorManager::~MotorManager() +{ + +} +bool MotorManager::GetOrSetUsbConnectFlag(bool isGet,bool value){ + if(isGet) + return is_usb_connect; + if(value == false) + m_ledcontrol->option(HG_LedOption::HG_WHITE_ON,300); + return is_usb_connect = value; +} + +bool MotorManager::GetOrSetSleepFlag(bool isGet,bool value){ + if(isGet) + return is_sleeping; + if(value == false) + { + if(!(m_sensormonitor->Is_ConverOpen()||m_sensormonitor->Is_Jam())) + { + if(!m_sensormonitor->Is_PaperOn()) + m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Reset); + m_ledcontrol->option(HG_WHITE_ON,0); + } + else{ + if(m_sensormonitor->Is_ConverOpen()) + m_ledcontrol->option(HG_RED_ON,300); + else + m_ledcontrol->option(HG_RED_ON,0); + } + } + else + is_autopaper = false; + if(mb_ev_cb_) + mb_ev_cb_(value ? SCANNER_STATUS_SLEEPING : SCANNER_STATUS_WAKED_UP); + + return is_sleeping = value; +} + +void MotorManager::set_capture(std::shared_ptr cap) +{ + m_cap = cap; +} +std::shared_ptr MotorManager::regs() +{ + return nullptr; +} +int MotorManager::os_mode(){ + return 0; +} +bool MotorManager::paper_ready(){ + return m_sensormonitor->Is_PaperOn(); +} +void MotorManager::clear_error(){ + mb_error = 0; +} + +void MotorManager::start(){ + is_motor_run = true; + m_papperout_time = std::chrono::steady_clock::now(); + m_motorcontrol->MotorRun(MotorControl::MotorOption::ZZ_Forward); + m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Forward); + GetorSetSysClassValue(false,HG_PWM_FAN,true); + GetorSetSysClassValue(false,HG_MOTOR_FAN,true); + m_ledcontrol->option(HG_WHITE_ON,0); +} +void MotorManager::stop(){ + is_motor_run = false; + m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Stop); + m_motorcontrol->MotorRun(MotorControl::MotorOption::ZZ_Stop); + GetorSetSysClassValue(false,HG_PWM_FAN,false); + GetorSetSysClassValue(false,HG_MOTOR_FAN,false); +} +bool MotorManager::wait_paper_out(int timeout_ms){ + return cv_paperout.wait(timeout_ms); +} +bool MotorManager::wait_paper_in(int timeout_ms){ + bool ret = cv_paperin.wait(timeout_ms); + std::cout<<"wait_paper_in timeout:"<MotorRun(MotorControl::MotorOption::CZ_Pause); + return ret; +} +void MotorManager::pick_paper(){ + m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Forward); +} + +void MotorManager::stop_pick_paper(){ + m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Pause); +} + +bool MotorManager::is_scanning(){ + return false; +} +bool MotorManager::is_jam(){ + return GetorSetSysClassValue(true,"/sys/class/gpio/gpio54/value",true); +} +int MotorManager::paper_counter(){ + return -1; +} +bool MotorManager::set_long_paper(bool enable){ + return false; +} +bool MotorManager::set_double_inpect(bool enable){ + if(enable) + //system("echo 1 > /sys/class/gpio/gpio139/value"); + GetorSetSysClassValue(false,"/sys/class/gpio/gpio139/value",true); + else + //system("echo 0 > /sys/class/gpio/gpio139/value"); + GetorSetSysClassValue(false,"/sys/class/gpio/gpio139/value",false); + return true; +} +bool MotorManager::set_staple_inpect(bool enable){ + return false; +} +bool MotorManager::set_auto_paper(bool enable){ + is_autopaper = enable; + return false; +} +bool MotorManager::set_color_mode(int mode){ + return false; +} + +int MotorManager::get_speed_mode(){ + return -1; +} + +bool MotorManager::set_speed_mode(int mode,int dpi,int iscolor){ + m_motorcontrol->setczspeed(mode,dpi,iscolor); + m_motorcontrol->setzzspeed(mode,dpi,iscolor); + return true; +} +bool MotorManager::set_screw_inpect(bool enable){ + return false; +} +bool MotorManager::get_screw_inpect(){ + return false; +} +bool MotorManager::set_screw_level(int level){ + return false; +} +int MotorManager::get_screw_level(){ + return -1; +} + +bool MotorManager::read(unsigned int addr, unsigned int &val){ + return false; +} +bool MotorManager::write(unsigned int addr, unsigned int val){ + return false; +} +bool MotorManager::set_cuospeed(unsigned int speed,uint dpi,uint iscolor){ + m_motorcontrol->setczspeed(speed,dpi,iscolor); + return true; +} +void MotorManager::set_callbacks(MotorBoardGlue glue){ + m_glue = glue; +} +bool MotorManager::get_keeplastpaper(){ + return false; +} +void MotorManager::motor_reset(){ + m_motorcontrol->MotorRun(MotorControl::CZ_Reset); +} + +void MotorManager::pincall(int value){ + if(mb_ev_cb_) + { + mb_ev_cb_(IMotorBoard::scanner_status_from_raw(value)); + } + if(is_sleeping || !is_usb_connect) + return; + printf("\npin call value %d",value); + if(value == 1){ + cv_paperin.notify_all(); + if(std::chrono::duration(std::chrono::steady_clock::now() - m_papperout_time).count() < 60) + m_glue.m_error_call?m_glue.m_error_call(0x40000):void(0); + printf("\n-------------- paper out time %f ---------------------------",std::chrono::duration(std::chrono::steady_clock::now() - m_papperout_time).count()); + m_papperout_time = std::chrono::steady_clock::now(); + } + else if(value == 0){ + cv_paperout.notify_all(); + m_papperout_time = std::chrono::steady_clock::now(); + } + if(value &0x24) + { + if(m_glue.m_error_call) + m_glue.m_error_call(value); + cv_paperin.notify_all(); + cv_paperout.notify_all(); + + } + if(value == 0x20) + { + this->stop(); + set_double_inpect(false); + } + if(value == 4 && is_converopen()) + m_ledcontrol->option(HG_RED_ON,300); + if(value ==0x4000000 && !is_motor_run) + { + f_motorreset = std::async(std::launch::async,[&](){ + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + if(is_usb_connect && !is_converopen() && (!paper_ready())) + motor_reset(),printf("\n conver reset"); + }); + printf("\n conver ******************************"); + if(is_jam()) + m_ledcontrol->option(HG_RED_ON,0); + else if(!is_usb_connect) + m_ledcontrol->option(HG_WHITE_ON,500); + else + m_ledcontrol->option(HG_WHITE_ON,0); + } + if(is_autopaper && value == 0x2000000 && !is_motor_run) + { + printf("\n ---------------------------------------------------"); + autopaper_state_change = true; + autopaperthread.enqueue([&]{ + StopWatch sw; + while (sw.elapsed_ms()<1000) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + if(!autopaper_state_change) + return; + } + m_glue.m_auto_paper(true); + printf("\n -----------------m_glue.m_auto_paper(true);----------------------------------"); + }); + } + if(is_autopaper && value == 2 && !is_motor_run) + { + autopaper_state_change = false; + } + if(value == 2){ + if(is_motor_run == false && is_converopen() == false && is_jam() == false && m_ledcontrol->get_state() == HG_LedOption::HG_RED_ON) + { + m_ledcontrol->option(HG_WHITE_ON,0); + if(mb_error == 8 || mb_error == 79 || mb_error == 82) + motor_reset(),mb_error = 0; + } + } +} +bool MotorManager::is_converopen() +{ + return m_sensormonitor->Is_ConverOpen(); +} + +void MotorManager::LedControlOption(HG_LedOption option,uint32_t time){ + m_ledcontrol?m_ledcontrol->option(option,time):void(1); +} + +void MotorManager::clean_paper_road(){ + set_speed_mode(1,2,0); + StopWatch sw; + m_motorcontrol->MotorRun(MotorControl::MotorOption::ZZ_Forward); + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + bool b_clean_ = false; + while(sw.elapsed_s() < 5) + { + if(!is_jam()) + { + b_clean_ = true; + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(700)); + } + m_motorcontrol->MotorRun(MotorControl::MotorOption::ZZ_Stop); + if(is_sleeping || !is_usb_connect) + return; + if(is_motor_run == false && is_converopen() == false && is_jam() == false && m_ledcontrol->get_state() == HG_LedOption::HG_RED_ON || b_clean_) + { + m_ledcontrol->option(HG_WHITE_ON,0); + } +} + +bool MotorManager::GetorSetSysClassValue(bool isGet,std::string path,bool value){ + if(isGet) + { + FILE *fp = fopen(path.c_str(),"r"); + if(fp != NULL) + { + fscanf(fp,"%d",&value); + fclose(fp); + return value; + } + return false; + } + else{ + FILE *fp = fopen(path.c_str(),"w"); + if(fp != NULL) + { + fprintf(fp,"%d",value); + fclose(fp); + return true; + } + return false; + } +} \ No newline at end of file diff --git a/device/gxx-linux/motorboard/motormanager.h b/device/gxx-linux/motorboard/motormanager.h new file mode 100644 index 0000000..1352e8e --- /dev/null +++ b/device/gxx-linux/motorboard/motormanager.h @@ -0,0 +1,72 @@ +#pragma once +#include "Imotorboard.h" +#include "autoevent.hpp" + +const std::string HG_PWM_FAN = "/sys/class/fv_en_class/fv_en/pwm_fan"; +const std::string HG_MOTOR_FAN = "/sys/class/fv_en_class/fv_en/motor_fan"; + +class MotorControl; +class SensorMonitor; +class LedControl; +enum HG_LedOption : uint8_t; + +class MotorManager : public IMotorBoard +{ +public: + MotorManager(); + virtual ~MotorManager(); + void start() override; + void stop() override; + void clear_error() override; + void pick_paper() override; + void stop_pick_paper() override; + int os_mode() override; + bool paper_ready() override; + bool is_converopen() override; + bool is_scanning() override; + bool is_jam() override; + int paper_counter() override; + bool set_long_paper(bool enable) override; + bool set_double_inpect(bool enable) override; + bool set_staple_inpect(bool enable) override; + bool set_auto_paper(bool enable) override; + bool set_color_mode(int mode) override; + int get_speed_mode() override; + bool set_speed_mode(int mode,int dpi,int iscolor) override; + bool set_screw_inpect(bool enable) override; + bool get_screw_inpect() override; + bool set_screw_level(int level) override; + int get_screw_level() override; + bool wait_paper_out(int timeout_ms) override; + bool wait_paper_in(int timeout_ms) override; + bool read(unsigned int addr, unsigned int &val) override; + bool write(unsigned int addr, unsigned int val) override; + bool set_cuospeed(unsigned int speed,uint dpi,uint iscolor) override; + void set_callbacks(MotorBoardGlue glue) override; + bool get_keeplastpaper() override; + std::shared_ptr regs() override; + void set_capture(std::shared_ptr cap) override; + void motor_reset() override; + bool GetOrSetUsbConnectFlag(bool isGet,bool value); + bool GetOrSetSleepFlag(bool isGet,bool value); + void LedControlOption(HG_LedOption option,uint32_t time) override; + void clean_paper_road() override; +private: + void pincall(int value); + bool GetorSetSysClassValue(bool isGet,std::string path,bool value); + std::unique_ptr m_motorcontrol; + std::unique_ptr m_sensormonitor; + std::unique_ptr m_ledcontrol; + MotorBoardGlue m_glue; + volatile bool is_usb_connect; + volatile bool is_sleeping; + volatile bool is_autopaper; + volatile bool is_motor_run; + volatile bool autopaper_state_change; + std::shared_ptr m_cap; + ThreadPool autopaperthread; + AutoSemaphore cv_paperin; + AutoSemaphore cv_paperout; + std::future f_motorreset; + std::chrono::steady_clock::time_point m_papperout_time; +}; diff --git a/device/gxx-linux/motorboard/sensormonitor.cpp b/device/gxx-linux/motorboard/sensormonitor.cpp new file mode 100644 index 0000000..09d9ac1 --- /dev/null +++ b/device/gxx-linux/motorboard/sensormonitor.cpp @@ -0,0 +1,127 @@ +#include "sensormonitor.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +SensorMonitor::SensorMonitor(std::function callback):m_callback(callback), + _C6(54),//扫描传感器 + _A4(36),//有无纸传感器 + _C7(55),//开盖传感器 + Double_out0(137)//超声波传感器 +{ + _C6.setDirection(Gpio::in); + _A4.setDirection(Gpio::in); + _C7.setDirection(Gpio::in); + Double_out0.setDirection(Gpio::in); + _C7.setEdge(Gpio::both); + _A4.setEdge(Gpio::both); + _C6.setEdge(Gpio::both); + Double_out0.setEdge(Gpio::rising); + is_paperon = _A4.getValue() == Gpio::GpioLevel::High ? false : true; + is_converopen = _C7.getValue() == Gpio::GpioLevel::High ? false : true; + is_jam = _C6.getValue() == Gpio::GpioLevel::High? true : false; + b_monitor = true; + m_monitor = std::thread(&SensorMonitor::monitor,this); +} + +SensorMonitor::~SensorMonitor() +{ + b_monitor =false; + if(m_monitor.joinable()) + m_monitor.join(); +} +bool SensorMonitor::Is_PaperOn() +{ + return is_paperon; +} + +bool SensorMonitor::Is_ConverOpen() +{ + return is_converopen; +} + +bool SensorMonitor::Is_Jam() +{ + return is_jam; +} + +void SensorMonitor::monitor(){ + pollfd fds[4]{}; + fds[0].fd = open(_C6.getValuePath().c_str(),O_RDONLY); + fds[1].fd = open(_A4.getValuePath().c_str(),O_RDONLY); + fds[2].fd = open(_C7.getValuePath().c_str(),O_RDONLY); + fds[3].fd = open(Double_out0.getValuePath().c_str(),O_RDONLY); + int ret=0; + char buf[8]{}; + int num =0; + num = read(fds[0].fd, buf, 8); + num = read(fds[1].fd, buf, 8); + num = read(fds[2].fd, buf, 8); + num = read(fds[3].fd, buf, 8); + while(b_monitor) + { + ret = poll(fds,4,1000); + if(ret>0) + { + if(fds[0].revents) + { + if(ret = readfile(fds[0].fd,num,buf)){ + if(m_callback) + m_callback(true); + is_jam = true; + } + else{ + if(m_callback) + m_callback(false); + is_jam = false; + } + printf("\n 扫描传感器 %d ",ret); + } + if(fds[1].revents) + { + if(readfile(fds[1].fd,num,buf)){ + is_paperon = false; + m_callback(2); + } + else{ + is_paperon = true; + m_callback(0x2000000); + } + printf("\n 有无纸传感器 %d ",!is_paperon); + } + if(fds[2].revents) + { + if(readfile(fds[2].fd,num,buf)){ + is_converopen = false; + m_callback(0x4000000); + } + else{ + is_converopen = true; + m_callback(4); + } + printf("\n 开盖传感器 %d ",!is_converopen); + } + if(fds[3].revents) + { + if(ret = readfile(fds[3].fd,num,buf)){ + m_callback(0x20); + } + printf("\n 双张 %d ",ret); + } + } + } +} +int SensorMonitor::readfile(int fd,int num , char* buf){ + lseek(fd, 0, SEEK_SET); + num = read(fd, buf, 8); + buf[num - 1] = '\0'; + return atoi(buf); +} \ No newline at end of file diff --git a/device/gxx-linux/motorboard/sensormonitor.h b/device/gxx-linux/motorboard/sensormonitor.h new file mode 100644 index 0000000..ee9e924 --- /dev/null +++ b/device/gxx-linux/motorboard/sensormonitor.h @@ -0,0 +1,29 @@ +#pragma once +#include "Gpio.h" +#include +#include +#include + +class SensorMonitor +{ +public: + SensorMonitor(std::function callback); + ~SensorMonitor(); + bool Is_PaperOn(); + bool Is_ConverOpen(); + bool Is_Jam(); +private: + void monitor(); + int readfile(int fd,int num , char* buf); + Gpio _C6; + Gpio _A4; + Gpio _C7; + Gpio Double_out0; + std::thread m_monitor; + std::function m_callback; + volatile bool b_monitor; + volatile bool is_converopen; + volatile bool is_paperon; + volatile bool is_jam; + +}; \ No newline at end of file diff --git a/device/gxx-linux/motorboard/xmake.lua b/device/gxx-linux/motorboard/xmake.lua index 62a0e90..6cca12f 100644 --- a/device/gxx-linux/motorboard/xmake.lua +++ b/device/gxx-linux/motorboard/xmake.lua @@ -4,6 +4,6 @@ target("motorboard") set_kind("static") add_syslinks("pthread") add_files("*.cpp") - add_deps("regs", "deviceio", "conf", "applog", "capimage",{public = true}) + add_deps("regs", "motor_run" ,"deviceio", "conf", "applog", "capimage",{public = true}) add_includedirs(".", { public = true}) add_packages("common") \ No newline at end of file diff --git a/device/gxx-linux/scanner/deviceconfig.cpp b/device/gxx-linux/scanner/deviceconfig.cpp index f4dbae2..ff654f9 100644 --- a/device/gxx-linux/scanner/deviceconfig.cpp +++ b/device/gxx-linux/scanner/deviceconfig.cpp @@ -61,11 +61,8 @@ json DeviceConfig::getdefaultjson() void DeviceConfig::savejson(json js) { - //std::lock_guard lc(m_lock); std::ofstream o(ParamPath); o << std::setw(4) << js <> m_json; - i.close(); return m_json; } diff --git a/device/gxx-linux/scanner/fsmstate.cpp b/device/gxx-linux/scanner/fsmstate.cpp index 526a466..57a9f90 100644 --- a/device/gxx-linux/scanner/fsmstate.cpp +++ b/device/gxx-linux/scanner/fsmstate.cpp @@ -1,7 +1,7 @@ #include "fsmstate.h" -#include "scanner.h" +#include "iscanner.h" -Scanner *FsmState::scanner = NULL; +IScanner *FsmState::scanner = NULL; #ifndef LOG #define LOG printf #endif diff --git a/device/gxx-linux/scanner/fsmstate.h b/device/gxx-linux/scanner/fsmstate.h index 6091e79..1b8e55d 100644 --- a/device/gxx-linux/scanner/fsmstate.h +++ b/device/gxx-linux/scanner/fsmstate.h @@ -4,7 +4,7 @@ #include #include -class Scanner; +class IScanner; enum ScanEvent { @@ -47,12 +47,12 @@ public: virtual FsmState* on_event(ScanEvent event) = 0; virtual void initial() {} - static void setScanner(Scanner* scan) { + static void setScanner(IScanner* scan) { scanner = scan; } std::string typeName = "FsmState"; protected: - static Scanner* scanner; + static IScanner* scanner; }; diff --git a/device/gxx-linux/scanner/iimagehandler.h b/device/gxx-linux/scanner/iimagehandler.h index e5e3a2e..eaf1c9b 100644 --- a/device/gxx-linux/scanner/iimagehandler.h +++ b/device/gxx-linux/scanner/iimagehandler.h @@ -2,6 +2,7 @@ #include "commondef.h" #include "ImageApplyHeaders.h" #include "CSizedetect.h" +#include "CorrectParam.h" #include #include #include @@ -15,8 +16,13 @@ static std::map papersize{ {B4, Size{250, 353}}, {B5, Size{176, 250}}, {B6, Size{125, 176}}, - {MaxSize, Size{297, 420 * 2}}, +#ifdef G300 + {MaxSize, Size{210, (long)(420 * 1.5)}}, + {USStatement, Size{210, (long)(420 * 1.5)}}, +#else + {MaxSize, Size{297, 1040}}, {USStatement, Size{297, (long)(420 * 1.5)}}, +#endif {USLetter, Size{216, 279}}, {USLegal, Size{216, 356}}, {USLedger, Size{279, 432}}, @@ -31,11 +37,12 @@ class IImageHandler { public: virtual ~IImageHandler() {} - virtual void add_image(void *data, int width, int height, int type,int scannnum) = 0; + virtual void add_image(void *data, int width, int height, int type,int scannnum,std::uint32_t fpga_vs,CISVendor cistype) = 0; virtual void config_procparams(HGImgProcParms params) = 0; virtual void add_scanevent(HGIntInfo status) = 0; virtual void clear() = 0; virtual bool done() = 0; + virtual bool is_limit() = 0; virtual void Set_ratio(u32 h_ratio,u32 v_ratio) = 0; ImgStatus getimgstatus() { return m_imgstatus;} void resetimgstatus() { m_imgstatus={.status=NO_error,.sannum=0};} @@ -64,25 +71,47 @@ public: { m_scanconfig = config; } + bool set_config(GScanCap config) { m_hgimgconfig = config; + if(config.resolution_dst<300.0f) + m_hgimgconfig.resolution_native = 200.0f; +#ifdef G300 + else + m_hgimgconfig.resolution_native = 300.0f; +#else + else if(config.resolution_dst <500.0f) + m_hgimgconfig.resolution_native = 300.0f; + else + m_hgimgconfig.resolution_native = 600.0f; +#endif m_ials.clear(); if(m_dog.get()) { if(m_hgimgconfig.dogeardistabce>=10 && m_hgimgconfig.dogeardistabce <=300) m_dog->setDistance(m_hgimgconfig.dogeardistabce); else - m_dog->setDistance(50); + m_dog->setDistance(70); } if(config.fillhole.is_fillhole) { - float ratio=config.fillhole.fillholeratio/100.0; - m_ials.push_back(std::shared_ptr(new CImageApplyOutHole(200.0f,ratio,50.0))); + if((config.fillholeratio_down+config.fillholeratio_up+config.fillholeratio_left+config.fillholeratio_right)>0) + { + m_ials.push_back(std::shared_ptr(new CImageApplyOutHole( + 25.0f, + {config.fillholeratio_up/100.0f,config.fillholeratio_down/100.0f,config.fillholeratio_left/100.0f,config.fillholeratio_right/100.0f}, + 50.0))); + } + else if(config.fillhole.fillholeratio > 0){ + float ratio=config.fillhole.fillholeratio/100.0; + m_ials.push_back(std::shared_ptr(new CImageApplyOutHole(25.0f,{ratio,ratio,ratio,ratio},50.0))); + } } - bool islongcustomcrop = config.papertype == 52; + bool islongcustomcrop = config.papertype == 52 || config.papertype == 0; //bool isautocrop = config.papertype == TwSS::None; Size fixedSize; + printf(" \nconfig.dogeardistabce=%d", config.dogeardistabce); printf(" \nconfig.papertype=%d", config.papertype); printf(" \nconfig.AutoCrop_threshold=%d", config.AutoCrop_threshold); printf(" \nconfig.autodescrew=%d", config.autodescrew); @@ -100,6 +129,7 @@ public: printf(" \nconfig.hardwarecaps.capturepixtype=%d", config.hardwarecaps.capturepixtype); printf(" \nconfig.hardwarecaps.en_doublefeed=%d", config.hardwarecaps.en_doublefeed); printf(" \nconfig.hsvcorrect=%d", config.hsvcorrect); + printf(" \nconfig.HsvFilterType=%d", config.HsvFilterType); printf(" \nconfig.imageRotateDegree=%d", config.imageRotateDegree); printf(" \nconfig.indent=%d", config.indent); printf(" \nconfig.is_autocontrast=%d", config.is_autocontrast); @@ -116,77 +146,28 @@ public: printf(" \nconfig.noise=%d", config.noise); printf(" \nconfig.hardwarecaps.paperAlign=%d", config.paperAlign); printf(" \nconfig.hardwarecaps.pixtype=%d", config.pixtype); - printf(" \nconfig.resolution_dst=%d", config.resolution_dst); - printf(" \nconfig.resolution_native=%d", config.resolution_native); + printf(" \nconfig.resolution_dst=%f", config.resolution_dst); + printf(" \nconfig.resolution_native=%f", config.resolution_native); printf(" \nconfig.scannum=%d", config.scannum); - printf(" \nconfig.sharpen=%d", config.sharpen); + printf(" \nconfig.sharpen=%d",config.sharpen); printf(" \nconfig.is_dogeardetection=%d", config.is_dogeardetection); - fixedSize = GetPaperSize(config.papertype, 200.0f, config.paperAlign); - // m_ials.push_back(shared_ptr(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : config.is_autocrop, - // config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,false,config.AutoCrop_threshold,config.noise,config.indent))); + fixedSize = GetPaperSize(config.papertype, m_hgimgconfig.resolution_native, config.paperAlign); + printf( " \n fixedSize x %d fixedSize y %d ",fixedSize.x,fixedSize.y); + config.is_autocrop = 1; + islongcustomcrop = false; + m_ials.push_back(shared_ptr(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : config.is_autocrop, + config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,false,config.AutoCrop_threshold,config.noise,config.indent))); if (config.is_autodiscradblank_normal || config.is_autodiscradblank_vince) { - //m_ials.push_back(shared_ptr(new CImageApplyDiscardBlank())); - CImageApplyDiscardBlank *disBlank = new CImageApplyDiscardBlank(); - //跳过空白页阈值 - int area = 200; - int intensity = 15; - int maxHeight = 3307; //A3 height - //页面最大高度获取 - if (config.papertype == 54) - maxHeight = 6614; - //阈值参数赋值 - if (config.discardblank_percent < 10) - { - area = 70 + (int)((config.discardblank_percent - 1) * 13.33); - intensity = 8 + config.discardblank_percent / 2; - } - else if (config.discardblank_percent < 20) - { - area = 190 + (config.discardblank_percent - 10) * 14; - intensity = 15; - } - else if (config.discardblank_percent < 40) - { - area = 400 + (config.discardblank_percent - 20) * 10; - intensity = 20; - } - else if (config.discardblank_percent < 60) - { - area = 600 + (config.discardblank_percent - 40) * 20; - intensity = 20; - } - else if (config.discardblank_percent < 80) - { - area = 1000 + (config.discardblank_percent - 60) * 55; - intensity = 30; - } + if (config.is_autodiscradblank_normal) + m_ials.push_back(shared_ptr(new CImageApplyDiscardBlank(40, 30, config.discardblank_percent, 200))); else - { - area = 2100 + (config.discardblank_percent - 80) * (maxHeight - 2100) / 20; - intensity = 40; - } - //判断是否为跳过空白页发票 - if (config.is_autodiscradblank_vince) - { - area *= 1.5; - intensity *= 1.5; - } - //设置参数阈值 - // disBlank->setMinArea(area); - // disBlank->setIntensity(intensity); - printf("\n area =%d,intensity =%d ",area,intensity); - m_ials.push_back(shared_ptr(disBlank)); - //m_ials.push_back(shared_ptr(new CImageApplyDiscardBlank(config.areanum,config.devnmax))); + m_ials.push_back(shared_ptr(new CImageApplyDiscardBlank(40, 30, config.discardblank_percent * 15 / 10, 150))); } m_ials.push_back(shared_ptr(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : config.is_autocrop, - config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,false,config.AutoCrop_threshold,config.noise,config.indent))); - - //除底色 - if(config.fadeback && config.pixtype == 2) - m_ials.push_back(shared_ptr(new CImageApplyFadeBackGroudColor(100,0,config.fadebackrange))); + config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,config.isfillcolor,config.AutoCrop_threshold,config.noise,config.indent,config.normalCrop,config.HsvFilterType == 0))); //自定义裁切 if(config.cropRect.enable &&!config.is_autocrop) @@ -194,7 +175,19 @@ public: printf("\n 自定义裁切"); m_ials.push_back(shared_ptr(new CImageApplyCustomCrop(cv::Rect(config.cropRect.x,config.cropRect.y,config.cropRect.width,config.cropRect.height)))); } + + m_hgimgconfig.is_colorcast = 0; + // if((config.pixtype == 2)&&(config.is_colorcast)) + // { + // printf("\n 色偏"); + // m_ials.push_back(m_colorcast); + // } + // if (config.fadeback && config.pixtype > 0)// && config.pixtype == 2 + { + printf("\n 除底色"); + m_ials.push_back(shared_ptr(new CImageApplyFadeBackGroudColor(50,0,config.fadebackrange))); + } // if (config.customGamma.enable) // { // m_iaList.push_back(shared_ptr(new CImageApplyCustomGamma(imgparams.customGamma.table, imgparams.customGamma.tableLength))); @@ -228,10 +221,16 @@ public: m_ials.push_back(shared_ptr(new CImageApplyAdjustColors(bright, contrast, config.gamma))); } //答题卡除红 - if (config.hsvcorrect && config.pixtype==2) + if ((config.hsvcorrect|| config.HsvFilterType!=0)&& config.pixtype==2) { printf("\n 答题卡除红"); - m_ials.push_back(shared_ptr(new CImageApplyHSVCorrect(CImageApplyHSVCorrect::CorrectOption::Red_Removal))); + CImageApplyHSVCorrect::CorrectOption hsv;//= config.hsvcorrect?CImageApplyHSVCorrect::CorrectOption::Red_Removal: + if(config.hsvcorrect) + hsv = CImageApplyHSVCorrect::CorrectOption::Red_Removal; + else + hsv = CImageApplyHSVCorrect::CorrectOption::FXB_Color_Cast; + + m_ials.push_back(shared_ptr(new CImageApplyHSVCorrect(hsv))); } //防止渗透 if (config.refuseInflow) @@ -269,7 +268,7 @@ public: islongcustomcrop = true; if (config.is_autocrop || islongcustomcrop) { - double ratio = config.resolution_dst / 200.0; // + double ratio = config.resolution_dst /m_hgimgconfig.resolution_native; // apply = new CImageApplyResize(CImageApplyResize::ResizeType::RATIO, cv::Size(0, 0), ratio, ratio); } else @@ -300,24 +299,29 @@ public: if (config.en_fold) { - m_ials.push_back(shared_ptr(new CImageApplyConcatenation(CImageApplyConcatenation::horizontal, cv::Scalar(255, 255, 255)))); + if(!(config.fold_concatmode >=0 && config.fold_concatmode <3)) + config.fold_concatmode = 0; + m_ials.push_back(shared_ptr(new CImageApplyConcatenation(CImageApplyConcatenation::ConcatMode(config.fold_concatmode), cv::Scalar(255, 255, 255)))); } + if (config.imageRotateDegree != 0.0 || config.is_backrotate180) { - CImageApplyRotation::RotationType type; - if (config.imageRotateDegree > 89.0f && config.imageRotateDegree < 91.0f) - type = CImageApplyRotation::RotationType::Rotate_90_clockwise; - else if (config.imageRotateDegree > 269.0f && config.imageRotateDegree < 271.0f) - type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise; - else if (config.imageRotateDegree > 179.0f && config.imageRotateDegree < 181.0f) - type = CImageApplyRotation::RotationType::Rotate_180; - else - type = CImageApplyRotation::RotationType::Invalid; + // CImageApplyRotation::RotationType type; + // if (config.imageRotateDegree > 89.0f && config.imageRotateDegree < 91.0f) + // type = CImageApplyRotation::RotationType::Rotate_90_clockwise; + // else if (config.imageRotateDegree > 269.0f && config.imageRotateDegree < 271.0f) + // type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise; + // else if (config.imageRotateDegree > 179.0f && config.imageRotateDegree < 181.0f) + // type = CImageApplyRotation::RotationType::Rotate_180; + // else + // type = CImageApplyRotation::RotationType::Invalid; - m_ials.push_back(shared_ptr(new CImageApplyRotation(type, config.is_backrotate180, config.resolution_dst, NULL))); + // m_ials.push_back(shared_ptr(new CImageApplyRotation(type, config.is_backrotate180, config.resolution_dst, NULL))); } + printf("Image processors: %d\n", m_ials.size()); + return true; } @@ -328,4 +332,5 @@ protected: std::vector> m_ials; std::shared_ptr m_dog; std::shared_ptr m_sizedetect; + // std::shared_ptr m_colorcast; }; diff --git a/device/gxx-linux/scanner/imagesavehandler.cpp b/device/gxx-linux/scanner/imagesavehandler.cpp index 97f9613..be9cda1 100644 --- a/device/gxx-linux/scanner/imagesavehandler.cpp +++ b/device/gxx-linux/scanner/imagesavehandler.cpp @@ -14,7 +14,7 @@ ImageSaveHandler::~ImageSaveHandler() } -void ImageSaveHandler::add_image(void *data, int width, int height, int type, int scannnum) +void ImageSaveHandler::add_image(void *data, int width, int height, int type, int scannnum,std::uint32_t fpga_vs,CISVendor cistype) { static int indexx = 0; std::string path = std::to_string(++indexx) + ".png"; diff --git a/device/gxx-linux/scanner/imagesavehandler.h b/device/gxx-linux/scanner/imagesavehandler.h index 82fc009..5bf1c81 100644 --- a/device/gxx-linux/scanner/imagesavehandler.h +++ b/device/gxx-linux/scanner/imagesavehandler.h @@ -8,7 +8,7 @@ class ImageSaveHandler : public IImageHandler public: ImageSaveHandler(); virtual ~ImageSaveHandler(); - virtual void add_image(void* data, int width, int height, int type ,int scannnum); + virtual void add_image(void* data, int width, int height, int type ,int scannnum,std::uint32_t fpga_vs,CISVendor cistype); virtual bool done(); private: diff --git a/device/gxx-linux/scanner/imageusbhandler.cpp b/device/gxx-linux/scanner/imageusbhandler.cpp index b6f103b..7d127ae 100644 --- a/device/gxx-linux/scanner/imageusbhandler.cpp +++ b/device/gxx-linux/scanner/imageusbhandler.cpp @@ -12,122 +12,161 @@ #include "ImageApplyAutoCrop.h" #include "hgutils.h" #include "correct_ultis.h" +#include +#include "../usb/src/common/packet.h" +#include "../usb/src/common/sys_util.h" + +namespace bmp +{ +#pragma pack(push) +#pragma pack(1) + typedef struct BITMAPFILEHEADER + { + u_int16_t bfType; + u_int32_t bfSize; + u_int16_t bfReserved1; + u_int16_t bfReserved2; + u_int32_t bfOffBits; + } BITMAPFILEHEADER; + + typedef struct BITMAPINFOHEADER + { + u_int32_t biSize; + u_int32_t biWidth; + u_int32_t biHeight; + u_int16_t biPlanes; + u_int16_t biBitCount; + u_int32_t biCompression; + u_int32_t biSizeImage; + u_int32_t biXPelsPerMeter; + u_int32_t biYPelsPerMeter; + u_int32_t biClrUsed; + u_int32_t biClrImportant; + } BITMAPINFODEADER; +#pragma pack(pop) + + int save_2_bmp_file(const char *bmp_file, void *buf, int w, int h, int resolution) + { + BITMAPINFOHEADER bih = {0}; + BITMAPFILEHEADER fh = {0}; + int pal_size = 0, line_len = (w * 24 + 31) / 32 * 4; + FILE *dst = fopen(bmp_file, "wb"); + + if (!dst) + return errno; + + bih.biSize = sizeof(bih); + bih.biWidth = w; + bih.biBitCount = 24; + bih.biSizeImage = h * line_len; + bih.biPlanes = 1; + bih.biHeight = h; + bih.biCompression = 0; + bih.biXPelsPerMeter = bih.biYPelsPerMeter = resolution * 39.37f + .5f; + + fh.bfType = 'B' | ('M' << 8); + fh.bfOffBits = sizeof(fh) + sizeof(bih) + pal_size; + fh.bfSize = fh.bfOffBits + bih.biSizeImage; + + fwrite(&fh, 1, sizeof(fh), dst); + fflush(dst); + + printf("width * 3 = %d, line bytes = %d\n", w * 3, line_len); + unsigned char *ptr = (unsigned char *)buf; + unsigned int pad = 0; + int pad_l = 4 - ((w * 3) % 4), step = w * 3; + + if (0) + { + ptr += w * 3 * (h - 1); + step *= -1; + } + if (line_len == w * 3) + { + bih.biHeight *= -1; + fwrite(&bih, 1, sizeof(bih), dst); + fwrite(buf, 1, bih.biSizeImage, dst); + } + else + { + fwrite(&bih, 1, sizeof(bih), dst); + for (int i = 0; i < h; ++i) + { + fwrite(ptr, w * 3, 1, dst); + fwrite(&pad, 1, pad_l, dst); + ptr += step; + } + } + fclose(dst); + + return 0; + } + +} static const std::string loggername = "imageusbhandler"; ImageUsbHandler::ImageUsbHandler(std::shared_ptr images) - : pool(1), encodepools(6),pushpool(1), que_len_(0) + : pool(1), encodepools(6), pushpool(1), que_len_(0) { LOG_INIT(); this->images = images; - m_dog.reset(new CImageApplyDogEarDetection(40,1.0,50)); + m_dog.reset(new CImageApplyDogEarDetection(40, 1.0, 50)); // m_colorcast.reset(new CImageApplyColorCastCorrect()); m_sizedetect.reset(new CSizedetect(1)); initLut(); - auto info= jsonconfig().getscannerinfo(); - H_ratio =*((float*)(&info.H_ratio)); - V_ratio =*((float*)(&info.V_ratio)); + auto info = jsonconfig().getscannerinfo(); + H_ratio = *((float *)(&info.H_ratio)); + V_ratio = *((float *)(&info.V_ratio)); } ImageUsbHandler::~ImageUsbHandler() { - } +static int push_img_data_times = 0; +static int take_img_data_times = 0; static int num = 0; -void ImageUsbHandler::add_image(void *data, int width, int height, int type, int scannnum,std::uint32_t fpga_vs,CISVendor cistype) +void ImageUsbHandler::add_image(void *data, int width, int height, int type, int scannnum, std::uint32_t fpga_vs, CISVendor cistype) { - printf("add_image(%u * %u)\n", width, height); + printf("\nadd_image(%u * %u), memory usage = %s\n", width, height, sys_util::format_readable_bytes(sys_util::get_memory_usage("scan")).c_str()); + + images->push(nullptr, false); + // bmp::save_2_bmp_file((std::string("/root/.scanner/log/cap_") + std::to_string(scannnum) + ".bmp").c_str(), data, width / 3, height, 200); + PACKIMAGE pkimg; + + memset(&pkimg, 0, sizeof(pkimg)); + pkimg.pos.paper_ind = scannnum; + pkimg.pos.status = IMG_STATUS_OK; + pkimg.pos.paper_side = PAPER_SIDE_LEFT; + std::string ext = ".jpg"; { if (m_imgstatus.status != NO_error) return; cv::Mat mat; - if(m_scanconfig.g200params.dpi == 3) + if (m_scanconfig.g200params.dpi == 3) mat = cv::Mat(height, width, CV_8UC1, data); else - mat = cv::Mat(height, width, CV_8UC1, data).clone(); + mat = cv::Mat(height, width, CV_8UC1, data).clone(); + printf("Image %d parameters: %d * %d * %d\n", scannnum, mat.cols, mat.rows, mat.channels() * 8); capture_data.Put(mat); StopWatch checktime; - if (m_hgimgconfig.is_dogeardetection || m_hgimgconfig.en_sizecheck) - { - cv::Mat tmp = cv::Mat(height, width, CV_8UC1, data); - if (tmp.empty()) - return; - m_imgstatus.status = Img_Detecting; -#ifdef G300 - auto mergemat = GetStitchMat(type == 16?1:0,width,height,tmp); -#else - auto mergemat = GetMergeMat(type == CV_8UC1 ? width : width / 3, height, type, tmp,0x90001); -#endif - if (m_scanconfig.g200params.dpi == 1) - cv::resize(mergemat, mergemat, cv::Size(0, 0), 200.0 / 300.0, 1.0); - else if (m_scanconfig.g200params.dpi == 2) - cv::resize(mergemat, mergemat, cv::Size(0, 0), 200.0 / 300.0, 200.0 / 300.0); - else - { -#ifdef G200 - cv::resize(mergemat,mergemat,cv::Size(0,0),200.0 / 600.0,1.43434/3); // 600 dpi ��������ʵ600�ɼ� -#elif defined G300 - cv::resize(mergemat,mergemat,cv::Size(0,0),200.0 / 600.0,1.432323/3); -#elif defined G400 - cv::resize(mergemat,mergemat,cv::Size(0,0),200.0 / 600.0,1.5/3); -#else - cv::resize(mergemat,mergemat,cv::Size(0,0),200.0 / 600.0,1.432323/3); -#endif - } - - if (m_hgimgconfig.is_dogeardetection) - { - printf("\n is_dogeardetection"); - if(!m_scanconfig.g200params.pc_correct) - correctColor(mergemat, false); - auto dogmat=mergemat(cv::Rect(mergemat.cols/2, 0, mergemat.cols/2, mergemat.rows)); - m_dog->apply(dogmat,0); - if(m_dog->getResult()) - { - m_imgstatus.status=Dog_error; - m_imgstatus.sannum=scannnum; - add_scanevent({.From=IMG,.Code=m_imgstatus.status,.Img_Index=m_imgstatus.sannum}); - return; - } - } - if(m_hgimgconfig.en_sizecheck) - { - auto sizemat=mergemat(cv::Rect(mergemat.cols/2, 0, mergemat.cols/2, mergemat.rows)); - printf("\n en_sizecheck %d",m_scanconfig.g200params.paper); - m_sizedetect->SetPapertype(m_scanconfig.g200params.paper); - if(m_sizedetect->preprocess(sizemat,NULL)) - { - m_imgstatus.status=Size_error; - m_imgstatus.sannum=scannnum; - add_scanevent({.From=IMG,.Code=m_imgstatus.status,.Img_Index=m_imgstatus.sannum}); - return; - } - } - m_imgstatus.status = NO_error; - } - //tmp.release(); - - //std::lock_guard guard(mtx); add_que_count(); results.emplace( - pool.enqueue([this, width, height, type, ext, scannnum, data,cistype] + pool.enqueue([this, width, height, type, ext, scannnum, data, cistype] { - printf("enqueue image index %d \n",scannnum); - StopWatch sw; - cv::Mat mat = capture_data.Take(); - if(m_scanconfig.g200params.dpi == 3) - mat = cv::Mat(height, width, CV_8UC1, data); - else - mat = cv::Mat(height, width, CV_8UC1, data).clone(); - capture_data.Put(mat); + printf("\nenqueue image index %d \n",scannnum); + StopWatch sw; + cv::Mat mat = capture_data.Take(); #ifdef G300 cv::Mat saveMat = GetStitchMat(type == 16?1:0,width,height,mat); #else int dstwidth = type==CV_8UC1?width:width/3; cv::Mat saveMat =GetMergeMat(dstwidth, height, type,mat,0x90001); #endif - printf("\n GetMergeMat time %f \n",sw.elapsed_ms()); + printf("Merged image: %d * %d * %d\n", saveMat.cols, saveMat.rows, saveMat.channels() * 8); + + //printf("\n GetMergeMat time %f \n",sw.elapsed_ms()); //cv::imwrite("/home/"+to_string(scannnum)+".png",saveMat); int dpi = saveMat.cols==7344?2:3; if(!m_scanconfig.g200params.pc_correct) @@ -137,7 +176,7 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int add_que_count(); encodeimgs.push(encodepools.enqueue([this,width,height,type,cistype]() -> std::vector { - auto saveMat = encode_data.Take(); + auto saveMat = encode_data.Take(); if(H_ratio>1.2f ||H_ratio<0.8f) H_ratio=1.0f; if(V_ratio>1.2f || V_ratio <0.8f) @@ -152,15 +191,17 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int cv::resize(saveMat,saveMat,cv::Size(),H_ratio,V_ratio); } if(m_scanconfig.g200params.dpi == 3) - #ifdef G200 - cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.43434*V_ratio); // 600 dpi ��������ʵ600�ɼ� - #elif defined G300 +#ifdef G200 + cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.43434*V_ratio); // 600 dpi ��������ʵ600�ɼ� +#elif defined G300 cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.432323*V_ratio); - #elif defined G400 +#elif defined G400 cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.5*V_ratio); - #else +#else cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.432323*V_ratio); - #endif +#endif + printf("dpi = %d, image = %d * %d * %d\n", m_scanconfig.g200params.dpi, saveMat.cols, saveMat.rows, saveMat.channels() * 8); + cv::Mat imageMat; std::vector imgs; int actwidth = saveMat.cols / 2; @@ -173,13 +214,12 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int imgs.push_back(imageMat); } } - // cv::imwrite("/home/proc.jpg",saveMat); - imgs.push_back(saveMat); - std::shared_ptr imageencode; //(new BmpImageEncode()); - std::vector encodedata; - bool iscorrect_mode =true; - if(!iscorrect_mode) - //if (!m_scanconfig.g200params.iscorrect_mode) + // imgs.push_back(saveMat); + std::shared_ptr imageencode; //(new BmpImageEncode()); + std::vector encodedata; + //bool iscorrect_mode =true; + //if(!iscorrect_mode) + if (!m_scanconfig.g200params.iscorrect_mode) { if (!m_hgimgconfig.is_switchfrontback && (imgs.size() > 1)) std::swap(imgs[0], imgs[1]); @@ -213,9 +253,10 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int cv::cvtColor(enMat,enMat,cv::COLOR_BGR2GRAY); } if(m_scanconfig.g200params.iscorrect_mode) - imageencode.reset(new JpegImageEncode(false)); + imageencode.reset(new JpegImageEncode(false, m_hgimgconfig.resolution_dst)); else - imageencode.reset(new JpegImageEncode(false)); + imageencode.reset(new JpegImageEncode(m_scanconfig.g200params.color?false:true, m_hgimgconfig.resolution_dst)); + encodedata.push_back(imageencode->encode(enMat)); } } @@ -229,20 +270,28 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int for (auto &data : mem) { if (data.get()) - images->push(data, true); + { + images->push(data, true); + } + else add_scanevent({.From = V4L2, .Code = 1}); } } + else + printf("!!!!!!!!! mem proc = empty vector \n"); + add_que_count(-1); }); - printf("imgproce time = %f \n", sw.elapsed_ms()); - LOG_TRACE(string_format("imgproce time = %f\n", sw.elapsed_ms())); })); - add_que_count(-1); + //printf("imgproce time = %f \n", sw.elapsed_ms()); + //LOG_TRACE(string_format("imgproce time = %f\n", sw.elapsed_ms())); + })); + add_que_count(-1); } } -bool ImageUsbHandler::is_limit(){ +bool ImageUsbHandler::is_limit() +{ if (m_hgimgconfig.resolution_dst > 200.0 || m_hgimgconfig.papertype == 52 || m_hgimgconfig.papertype == 54 || m_hgimgconfig.papertype == 131) { @@ -250,7 +299,7 @@ bool ImageUsbHandler::is_limit(){ { results.front().get(); { - //std::lock_guard guard(mtx); + // std::lock_guard guard(mtx); results.pop(); } } @@ -265,7 +314,7 @@ bool ImageUsbHandler::is_limit(){ { results.front().get(); { - //std::lock_guard guard(mtx); + // std::lock_guard guard(mtx); results.pop(); } } @@ -277,11 +326,10 @@ bool ImageUsbHandler::is_limit(){ return false; } - void ImageUsbHandler::thread_push_stop_event(HGIntInfo ev) { printf("Received STOPSCAN event, but image-process is busying, wait real stop in thread ...\n"); - while(!done()) + while (!done()) { std::this_thread::sleep_for(std::chrono::milliseconds(3)); } @@ -307,9 +355,9 @@ int32_t ImageUsbHandler::add_que_count(int adden) void ImageUsbHandler::add_scanevent(HGIntInfo status) { printf("add_scanevent(%d)\n", status.From); - if(status.From == STOPSCAN && !done()) + if (status.From == STOPSCAN && !done()) { - if(stop_event_thread_.get() && stop_event_thread_->joinable()) + if (stop_event_thread_.get() && stop_event_thread_->joinable()) stop_event_thread_->join(); stop_event_thread_.reset(new std::thread(&ImageUsbHandler::thread_push_stop_event, this, status)); } @@ -330,39 +378,58 @@ void ImageUsbHandler::clear() capture_data.Clear(); } -void ImageUsbHandler::Set_ratio(u32 h_ratio,u32 v_ratio) +void ImageUsbHandler::Set_ratio(u32 h_ratio, u32 v_ratio) { - H_ratio =*((float*)(&h_ratio)); - //V_ratio =*((float*)(&v_ratio)); + H_ratio = *((float *)(&h_ratio)); + // V_ratio =*((float*)(&v_ratio)); V_ratio = 1.0f; } bool ImageUsbHandler::done() { - return add_que_count(0) == 0; + // return add_que_count(0) == 0; - bool over = true; - { - std::lock_guard guard(mtx); - if(results.size() >= 1){ - auto &fu_run = results.back(); - if((fu_run.valid() && (fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready))) - over = false; - } - if(over && encodeimgs.size()>=1) - { - auto &fu_encode = encodeimgs.back(); - over = !fu_encode.valid() || encodeimgs.size() == 0; - // if((!fu_encode.valid()) && encodeimgs.size() == 1) - // over = true; - // else - // over = false; - // return !(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready); - //return (!(fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready))&&(!(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready)); - } + // bool over = true; + // { + // std::lock_guard guard(mtx); + // if (results.size() >= 1) + // { + // auto &fu_run = results.back(); + // if ((fu_run.valid() && (fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready))) + // over = false; + // } + // if (over && encodeimgs.size() >= 1) + // { + // auto &fu_encode = encodeimgs.back(); + // over = !fu_encode.valid() || encodeimgs.size() == 0; + // // if((!fu_encode.valid()) && encodeimgs.size() == 1) + // // over = true; + // // else + // // over = false; + // // return !(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready); + // // return (!(fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready))&&(!(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready)); + // } + // } + + // return over; + std::lock_guard guard(mtx); + if(results.size() >= 1){ + auto &fu_run = results.back(); + if((fu_run.valid() && (fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready))) + return false; } + if(encodeimgs.size()>=1) + { + auto &fu_encode = encodeimgs.back(); + if((!fu_encode.valid()) && encodeimgs.size() == 1) + return true; + else + return false; + return !(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready); + //return (!(fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready))&&(!(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready)); - return over; + } + return true; } void ImageUsbHandler::config_procparams(HGImgProcParms params) @@ -376,3 +443,61 @@ void ImageUsbHandler::config_procparams(HGImgProcParms params) LOG_TRACE(string_format("HGImgProcParms.fillhole = %d \n", params.imgprocparams.fillhole)); m_procparams = params; } + +//{ +// "montage": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 10, +// "unit" : "None", +// "title" : "图像拼接", +// "desc" : "将CIS采集的原始数据恢复为正常的图像", +// "type" : "bool", +// "cur" : true, +// "default" : true, +// "size" : 4, +// }, +// "fb-split": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 20, +// "unit" : "None", +// "title" : "拆分正反面", +// "desc" : "将正反面合成的一张图片,拆分成正面和反面图片", +// "type" : "bool", +// "cur" : true, +// "default" : true, +// "size" : 4, +// "depend_and": ["montage==true"] +// } +//} +// +// +// +//{ +// "compress": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "imgproc", +// "pos" : 9999, +// "unit" : "None", +// "title" : "图像压缩", +// "desc" : "图片压缩成指定文件格式", +// "type" : "string", +// "cur" : "jpeg", +// "default" : "jpeg", +// "size" : 32, +// "range": ["none", "zip", "jpeg", "png", "bmp"] // none & zip 方式的数据为PACKIMAGE + 图像点阵数据 +// } +//} diff --git a/device/gxx-linux/scanner/imageusbtesthandler.cpp b/device/gxx-linux/scanner/imageusbtesthandler.cpp index 43912d4..2ebd7bc 100644 --- a/device/gxx-linux/scanner/imageusbtesthandler.cpp +++ b/device/gxx-linux/scanner/imageusbtesthandler.cpp @@ -14,7 +14,7 @@ ImageUsbTestHandler::ImageUsbTestHandler(std::shared_ptr imag { } -void ImageUsbTestHandler::add_image(void* data, int width, int height, int type ,int scannnum) +void ImageUsbTestHandler::add_image(void* data, int width, int height, int type ,int scannnum,std::uint32_t fpga_vs,CISVendor cistype) { // results.emplace_back( // pool.enqueue([this, data, width, height, type] diff --git a/device/gxx-linux/scanner/imageusbtesthandler.h b/device/gxx-linux/scanner/imageusbtesthandler.h index b056ebf..7d87b5d 100644 --- a/device/gxx-linux/scanner/imageusbtesthandler.h +++ b/device/gxx-linux/scanner/imageusbtesthandler.h @@ -6,5 +6,5 @@ class ImageUsbTestHandler : public ImageUsbHandler { public: ImageUsbTestHandler(std::shared_ptr images = nullptr); - virtual void add_image(void* data, int width, int height, int type,int scannnum); + virtual void add_image(void* data, int width, int height, int type,int scannnum,std::uint32_t fpga_vs,CISVendor cistype); }; \ No newline at end of file diff --git a/device/gxx-linux/scanner/iscanner.cpp b/device/gxx-linux/scanner/iscanner.cpp new file mode 100644 index 0000000..4c1cef0 --- /dev/null +++ b/device/gxx-linux/scanner/iscanner.cpp @@ -0,0 +1,344 @@ +#include "iscanner.h" +#include +#include "Imotorboard.h" +#include "Capturer.h" +#include +#include "StopWatch.h" +#include "iimagehandler.h" +#include "correct_ultis.h" +#include "applog.h" +#include "stringex.hpp" +#include "fpgacontrol.h" +#include "scannerregs.h" +#include "fpgacontrol.h" +#include "Gpio.h" +#include "deviceconfig.h" +#include +#include +#include +#include + +static const std::string loggername = "IScanner"; + +IScanner::IScanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake) + : bMsgLoop(true), + scancount(1024) +// testGpio(new Gpio(153)) +{ + LOG_INIT(); + this->wake = wake; + this->mb = mb; + this->capturer = capturer; + mb->set_capture(capturer); + scannerinfo = getscannerinfo(); + auto capturecallback = [&](int cap_call_code, std::string s_info) + { + HGIntInfo info = {.From = AutoCorrect, .Code = cap_call_code, .Img_Index = s_info.length()}; + imagehandler->add_scanevent(info); + if (s_info.length() > 0) + ((ScannerRegAccess *)m_parent)->write_info(s_info); + }; + this->capturer->setcapturecall(capturecallback); +} + +IScanner::~IScanner() +{ + bMsgLoop = false; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + sysEvent.Put(ScanEvent::S_EVT_STOP_SCAN); + + if (threadRunMessageLoop.joinable()) + threadRunMessageLoop.join(); +} +bool IScanner::check_scan(std::string encodehexstr){ + bool is_scan = true; + if(DeviceConfig().GetParam().is_lock) + { + auto tmp_token = DeviceConfig().GetParam().token; + if((encodehexstr.length() != 32) || (tmp_token.length() !=32)) + is_scan = false; + else{ + AES_KEY aes_key; + std::uint8_t key[16] ={0}; + //tmp_token = "C34E58CD5F3F2FF703E1AA24892FBD69"; + printf("tmp_token %s",tmp_token); + for(int i =0;i<16;i++) + { + key[i] = std::strtol(tmp_token.substr(i*2,2).c_str(),nullptr,16); + } + if(AES_set_decrypt_key(key,128,&aes_key)< 0) + { + is_scan = false; + } + std::uint8_t cipher[16] ={0}; + std::uint8_t decode[16] ={0}; + for(int i =0;i<16;i++) + { + cipher[i] = std::strtol(encodehexstr.substr(i*2,2).c_str(),nullptr,16); + } + + AES_ecb_encrypt(cipher,decode,&aes_key,AES_DECRYPT); + for(int i =0;iadd_scanevent({.From = MtBoard, 0x100}); + if (m_config.g200params.is_autopaper) + imagehandler->add_scanevent({.From = STOPSCAN, 1}); + imagehandler->add_scanevent({.From = STOPSCAN, 0}); + } + return is_scan; +} + +std::string IScanner::getmbversion() +{ + return mbversion; +} + +void IScanner::add_scansever(HGIntInfo event) +{ + if (imagehandler.get()) + imagehandler->add_scanevent(event); +} + +bool IScanner::set_hgimgconfig(GScanCap config) +{ + printf("enter config set_hgimgconfig \n"); + scancount = config.is_duplex ? config.scannum / 2 : config.scannum; + m_cap = config; + mb->set_scancap(config); + if(config.resolution_dst < 300) + m_config.g200params.dpi = 1; +#ifdef G300 + else + m_config.g200params.dpi = 2; +#else + else if ((config.resolution_dst >= 300) &&(config.resolution_dst < 500)) + m_config.g200params.dpi = 2; + else + m_config.g200params.dpi = 3; +#endif + if(config.HsvFilterType!=0 || config.filter!=3 ||config.fadeback!=0) + m_config.g200params.color = 1; + + printf("\n m_config.g200params.dpi =%d",m_config.g200params.dpi); + imagehandler->set_scanconfig(m_config); + if (config.is_autocrop && (config.papertype == 0)&&m_config.g200params.en_autosize) + m_config.g200params.paper = 16; + if(config.papertype == 54) + m_config.g200params.paper = m_config.g200params.en_autosize? 16 : 17; + if(config.papertype == 52 || config.papertype == 131) + m_config.g200params.paper = m_config.g200params.en_autosize? 16 : 18; + if (imagehandler.get()) + { + imagehandler->clear(); + return imagehandler->set_config(config); + } + return false; +} + +void IScanner::configparam(HGScanConfig config) +{ + LOG_TRACE(string_format("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ", + config.g200params.color, + config.g200params.dpi, + config.g200params.paper, + config.g200params.double_feed_enbale, + config.g200params.stable_enbale, + config.g200params.iscorrect_mode, + config.g200params.pc_correct)); + printf("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ", + config.g200params.color, + config.g200params.dpi, + config.g200params.paper, + config.g200params.double_feed_enbale, + config.g200params.stable_enbale, + config.g200params.iscorrect_mode, + config.g200params.pc_correct); + imagehandler->set_scanconfig(config); + m_config = config; + if (config.g200params.iscorrect_mode) + { + scancount = 65535; + } +} + + + +int IScanner::getimageprocedone() +{ + if (imagehandler.get()) + return imagehandler->done(); + return true; +} + +void IScanner::test_autocorrect(int colormode) +{ + printf("color mode =%s \n", colormode == 1 ? "COLOR" : "GRAY"); + capturer->init_autocorrect(colormode); +} +bool IScanner::is_runscan() +{ + return (fu_runscan && fu_runscan->is_runing()) || (imagehandler && !imagehandler->done()); +} + +void IScanner::set_imagehandler(std::shared_ptr handler) +{ + imagehandler = handler; +} + +void IScanner::clear_error() +{ + mb->clear_error(); +} + +void IScanner::runMessageLoop() +{ + FsmState *fsmState = FsmStateManagerEx::GetState(); + FsmState::setScanner(this); + do + { + ScanEvent evt = sysEvent.Take(); + fsmState = fsmState->on_event(evt); + } while (bMsgLoop); +} + +bool IScanner::paper_ready() +{ + return mb->paper_ready(); +} + +bool IScanner::get_keeplastpaper() +{ + return mb->get_keeplastpaper(); +} + +void IScanner::startcapimage() +{ + FILE * fp =fopen("/sys/class/tty/ttyUSB0/device/huagao_scanner","w"); + if (fp == NULL) + perror("startcapimage open filed"); + else + fprintf(fp,"%d",1); + + fclose(fp); +} + +void IScanner::set_motorboardcallback(MotorBoardGlue glue) +{ + + mb->set_callbacks(glue); +} + +void IScanner::set_imgprocparams(HGImgProcParms params) +{ + imagehandler->config_procparams(params); +} + +void IScanner::test_cap(HGScanConfig config) +{ + printf("capturer openning \n"); + FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color); + capturer->open(config,fpgaparam); + capturer->snap(); + void *data; + if (data = capturer->readFrame(2000)) + { + int imtype = capturer->color() ? CV_8UC3 : CV_8UC1; + cv::Mat mat; + cv::Mat saveMat; + std::vector ch_mats; + int dstwidth, dstheight; + int width = capturer->width(); + int height = capturer->height(); + dstwidth = width * 3; + dstheight = height / 3; + + if (imtype == CV_8UC3) + { + mat = cv::Mat(height / 3, width * 9, CV_8UC1, data); + saveMat = cv::Mat(dstheight, dstwidth, CV_8UC3); + } + + else + { // gray + saveMat = cv::Mat(height, width * 3, CV_8UC1, data); + } + static int savenum; + if (imtype == CV_8UC3) + { + for (int i = 0; i < 3; i++) + { // B G R + cv::Mat mattemp = mat(cv::Rect(dstwidth * i, 0, dstwidth, dstheight)); + ch_mats.push_back(mattemp); + } + swap(ch_mats[1], ch_mats[2]); + cv::merge(ch_mats, saveMat); + } + //cv::imwrite(std::to_string(++savenum) + ".jpg", saveMat); + } + else + { + printf("LOST Image \n"); + } + capturer->close(); + printf("capturer closed \n"); +} +void IScanner::set_sleeptime(int val) +{ + if (wake.get()) + wake->settime(val); +} + +int IScanner::get_sleeptime() +{ + if (wake.get()) + return wake->gettime(); + return 0; +} + +void IScanner::resettime() +{ + if (wake.get()) + wake->resettime(); +} + +int IScanner::get_sleepstatus() +{ + if (wake.get()) + return wake->get_status(); + return 0; +} + +void IScanner::set_paprent(void *parent) +{ + if (parent) + m_parent = parent; +} +void IScanner::set_sleepstatus(bool off) +{ + if (wake.get()) + { + if (off) + wake->power_on(); + else + wake->power_off(); + } +} + + +void IScanner::clean_paper_road(){ + if(mb.get()) + mb->clean_paper_road(); +} \ No newline at end of file diff --git a/device/gxx-linux/scanner/iscanner.h b/device/gxx-linux/scanner/iscanner.h new file mode 100644 index 0000000..5abc5ff --- /dev/null +++ b/device/gxx-linux/scanner/iscanner.h @@ -0,0 +1,71 @@ +#pragma once +#include +#include +#include "BlockingQueue.h" +#include "fsmstate.h" +#include +#include "commondef.h" +#include "wakeup.hpp" +#include + + +class IMotorBoard; +class ICapturer; +class IImageHandler; +class Gpio; + +class IScanner +{ +public: + IScanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake); + virtual ~IScanner(); + virtual void start_scan() = 0; + virtual void stop_scan() = 0; + virtual int count() = 0; + virtual int mode() = 0; + virtual int getmbstatus() = 0; + virtual bool getpaperon() = 0; + virtual void runScan() = 0; + void clean_paper_road(); + bool check_scan(std::string encodehexstr); + void configparam(HGScanConfig config); + void put(ScanEvent evt) { sysEvent.Put(evt); } + bool is_runscan(); + void set_imagehandler(std::shared_ptr handler = nullptr); + void clear_error(); + bool paper_ready(); + bool get_keeplastpaper(); + void set_motorboardcallback(MotorBoardGlue glue); + void set_imgprocparams(HGImgProcParms parmas); + void test_autocorrect(int colormode); + void test_cap(HGScanConfig config); + bool set_hgimgconfig(GScanCap config); + void add_scansever(HGIntInfo event); + void set_sleeptime(int val); + int get_sleeptime(); + void resettime(); + int get_sleepstatus(); + void set_sleepstatus(bool off); + int getimageprocedone(); + void set_paprent(void* parent); + std::string getmbversion(); + void runMessageLoop(); + void startcapimage(); +protected: + std::thread threadRunMessageLoop; + volatile bool bMsgLoop = true; + BlockingQueue sysEvent; + std::shared_ptr mb; + std::shared_ptr capturer; + std::shared_ptr wake; + std::shared_ptr fu_runscan; + std::shared_ptr m_capturereload; + std::shared_ptr imagehandler; + std::function m_mtcallback; + int scancount=0; + HGScanConfig m_config; + GScanCap m_cap; + ScannerNativeParam scannerinfo; + void* m_parent; + std::string mbversion; +}; diff --git a/device/gxx-linux/scanner/scanner.cpp b/device/gxx-linux/scanner/scanner.cpp index d543c3b..abbf90b 100644 --- a/device/gxx-linux/scanner/scanner.cpp +++ b/device/gxx-linux/scanner/scanner.cpp @@ -1,6 +1,6 @@ #include "scanner.h" #include -#include "motorboard.h" +#include "Imotorboard.h" #include "Capturer.h" #include #include "StopWatch.h" @@ -11,24 +11,13 @@ #include "scannerregs.h" #include "fpgacontrol.h" #include "Gpio.h" -#include "deviceconfig.h" -#include -#include -#include -#include +#include "correct_ultis.h" static const std::string loggername = "Scanner"; -Scanner::Scanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake) - : bMsgLoop(true), - scancount(1024) -// testGpio(new Gpio(153)) +Scanner::Scanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake):IScanner(capturer,mb,wake) { LOG_INIT(); - this->wake = wake; - this->mb = mb; - this->capturer = capturer; - // threadRunMessageLoop = std::move(std::thread(&Scanner::runMessageLoop, this)); auto mb_error_call = [&](unsigned int error_code) { int code = 0; @@ -140,7 +129,7 @@ Scanner::Scanner(std::shared_ptr capturer, std::shared_ptr capturer, std::shared_ptrset_callbacks(mb_glue); - mb->set_capture(capturer); - scannerinfo = getscannerinfo(); - auto capturecallback = [&](int cap_call_code, std::string s_info) - { - HGIntInfo info = {.From = AutoCorrect, .Code = cap_call_code, .Img_Index = s_info.length()}; - imagehandler->add_scanevent(info); - if (s_info.length() > 0) - ((ScannerRegAccess *)m_parent)->write_info(s_info); - }; - this->capturer->setcapturecall(capturecallback); - mb->set_auto_paper(m_config.g200params.is_autopaper); //防止程序异常死掉后未关闭连续扫描导致升降台抬升扫�? + mb->set_auto_paper(m_config.g200params.is_autopaper); //防止程序异常死掉后未关闭连续扫描导致升降台抬升扫描 u32 value; mb->read(0x00, value); - printf("mb reg[0] = 0x%x \n", value); + printf("mb reg[0] = %d \n", value); value = 0; mb->read(0x03, value); if (value >= 35211210) @@ -174,143 +153,12 @@ Scanner::Scanner(std::shared_ptr capturer, std::shared_ptropen(); + printf("mb reg[0] = %d \n", value); } Scanner::~Scanner() { - bMsgLoop = false; - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - sysEvent.Put(ScanEvent::S_EVT_STOP_SCAN); - if (threadRunMessageLoop.joinable()) - threadRunMessageLoop.join(); -} - -void Scanner::try_scan(const std::string encodehexstr) -{ - bool is_scan = true; - printf("\n encodehexstr = "); - for(int i =0;iadd_scanevent({.From = MtBoard, 0x100}); - if (m_config.g200params.is_autopaper) - imagehandler->add_scanevent({.From = STOPSCAN, 1}); - imagehandler->add_scanevent({.From = STOPSCAN, 0}); - } -} - -std::string Scanner::getmbversion() -{ - return mbversion; -} - -void Scanner::add_scansever(HGIntInfo event) -{ - if (imagehandler.get()) - imagehandler->add_scanevent(event); -} - -bool Scanner::set_hgimgconfig(GScanCap config) -{ - printf("enter config set_hgimgconfig \n"); - scancount = config.is_duplex ? config.scannum / 2 : config.scannum; - m_cap = config; - if (imagehandler.get()) - { - imagehandler->clear(); - return imagehandler->set_config(config); - } - return false; -} - -void Scanner::configparam(HGScanConfig config) -{ - LOG_TRACE(string_format("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ", - config.g200params.color, - config.g200params.dpi, - config.g200params.paper, - config.g200params.double_feed_enbale, - config.g200params.stable_enbale, - config.g200params.iscorrect_mode, - config.g200params.pc_correct)); - printf("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ", - config.g200params.color, - config.g200params.dpi, - config.g200params.paper, - config.g200params.double_feed_enbale, - config.g200params.stable_enbale, - config.g200params.iscorrect_mode, - config.g200params.pc_correct); - imagehandler->set_scanconfig(config); - m_config = config; - if (config.g200params.iscorrect_mode) - { - scancount = 65535; - } } void Scanner::start_scan() @@ -321,7 +169,8 @@ void Scanner::start_scan() if (wake.get()) wake->setsleepfalg(true); mb_error_code = is_ml_top = handstop = false; - capturer->open(m_config); + FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color); + capturer->open(m_config,fpgaparam); scannerinfo = getscannerinfo(); int spdmode = 0; if (scannerSp.count((SpeedMode)scannerinfo.speedmode) <= 0) @@ -336,10 +185,8 @@ void Scanner::start_scan() { spdmode = scannerSp[(SpeedMode)scannerinfo.speedmode].motorSpeed; } - mb->set_speed_mode(spdmode); - imagehandler->Set_ratio(scannerinfo.H_ratio,scannerinfo.V_ratio); + mb->set_speed_mode(spdmode,1,1); printf("\n set speedmode %d read speedmode %d", spdmode, mb->get_speed_mode()); - // capturer->open(); imagehandler->resetimgstatus(); mb->clear_error(); fu_runscan.reset(new ThreadEx(&Scanner::runScan, this)); @@ -362,14 +209,6 @@ int Scanner::mode() { return mb->os_mode(); } - -int Scanner::getimageprocedone() -{ - if (imagehandler.get()) - return imagehandler->done(); - return true; -} - int Scanner::getmbstatus() { mb->clear_error(); @@ -379,57 +218,6 @@ int Scanner::getmbstatus() return val & 0x700fe; } -void Scanner::test_autocorrect(int colormode) -{ - printf("color mode =%s \n", colormode == 1 ? "COLOR" : "GRAY"); - capturer->init_autocorrect(colormode); -} -bool Scanner::is_runscan() -{ - return (fu_runscan && fu_runscan->is_runing()) || (imagehandler && !imagehandler->done()); -} - -void Scanner::set_imagehandler(std::shared_ptr handler) -{ - imagehandler = handler; -} - -void Scanner::clear_error() -{ - mb->clear_error(); -} - -void Scanner::runMessageLoop() -{ - FsmState *fsmState = FsmStateManagerEx::GetState(); - FsmState::setScanner(this); - do - { - ScanEvent evt = sysEvent.Take(); - fsmState = fsmState->on_event(evt); - } while (bMsgLoop); -} - -bool Scanner::paper_ready() -{ - return mb->paper_ready(); -} - -bool Scanner::get_keeplastpaper() -{ - return mb->get_keeplastpaper(); -} - -void Scanner::startcapimage() -{ - FILE * fp =fopen("/sys/class/tty/ttyUSB0/device/huagao_scanner","w"); - if (fp == NULL) - perror("startcapimage open filed"); - else - fprintf(fp,"%d",1); - - fclose(fp); -} static int pickpapernum = 0; void Scanner::runScan() @@ -457,11 +245,9 @@ void Scanner::runScan() imagehandler->add_scanevent({.From = MtBoard, .Code = 4}); LOG_TRACE("\nCover Open status"); imagehandler->add_scanevent({.From = STOPSCAN, 0}); - } - if (m_config.g200params.is_autopaper) - { - imagehandler->add_scanevent({.From = STOPSCAN, 1}); - mb->set_auto_paper(false); + if (mb_error_code != 0 && m_config.g200params.is_autopaper) + mb->set_auto_paper(false); + return; } imagehandler->add_scanevent({.From = MtBoard, .Code = val & 0x700fe}); printf("\n scan stop code =%d ", val & 0x700fe); @@ -480,14 +266,8 @@ void Scanner::runScan() } if (!is_ml_top || mb_error_code || handstop) { - if (mb_error_code == 0 && handstop == 0) // 无其他异常时,发送升降台未到达指定位置异�? - { + if (mb_error_code == 0 && handstop == 0) // 无其他异常时,发送升降台未到达指定位置异常 imagehandler->add_scanevent({.From = MtBoard, 0x80000}); - if (m_config.g200params.is_autopaper) - mb->set_auto_paper(false); - } - capturer->stop(); - capturer->close(); capturer->reset(); this_thread::sleep_for(chrono::milliseconds(20)); imagehandler->add_scanevent({.From = STOPSCAN, 0}); @@ -509,126 +289,25 @@ void Scanner::runScan() wake->resettime(); wake->setsleepfalg(false); } - - capturer->reset(); imagehandler->add_scanevent({.From = STOPSCAN, 0}); - if ((mb_error_code != 0 || imagehandler->getimgstatus().status != NO_error ) && m_config.g200params.is_autopaper) + capturer->reset(); + if (mb_error_code != 0 && m_config.g200params.is_autopaper) mb->set_auto_paper(false); printf("\n-------scanner done-------\n"); } -void Scanner::set_motorboardcallback(MotorBoardGlue glue) -{ - - mb->set_callbacks(glue); -} - -void Scanner::set_imgprocparams(HGImgProcParms params) -{ - imagehandler->config_procparams(params); -} - -void Scanner::test_cap(HGScanConfig config) -{ - printf("capturer openning \n"); - capturer->open(config); - capturer->snap(); - void *data; - if (data = capturer->readFrame(2000)) - { - int imtype = capturer->color() ? CV_8UC3 : CV_8UC1; - cv::Mat mat; - cv::Mat saveMat; - std::vector ch_mats; - int dstwidth, dstheight; - int width = capturer->width(); - int height = capturer->height(); - dstwidth = width * 3; - dstheight = height / 3; - - if (imtype == CV_8UC3) - { - mat = cv::Mat(height / 3, width * 9, CV_8UC1, data); - saveMat = cv::Mat(dstheight, dstwidth, CV_8UC3); - } - - else - { // gray - saveMat = cv::Mat(height, width * 3, CV_8UC1, data); - } - static int savenum; - if (imtype == CV_8UC3) - { - for (int i = 0; i < 3; i++) - { // B G R - cv::Mat mattemp = mat(cv::Rect(dstwidth * i, 0, dstwidth, dstheight)); - ch_mats.push_back(mattemp); - } - swap(ch_mats[1], ch_mats[2]); - cv::merge(ch_mats, saveMat); - } - cv::imwrite(std::to_string(++savenum) + ".jpg", saveMat); - } - else - { - printf("LOST Image \n"); - } - capturer->close(); - printf("capturer closed \n"); -} -void Scanner::set_sleeptime(int val) -{ - if (wake.get()) - wake->settime(val); -} - -int Scanner::get_sleeptime() -{ - if (wake.get()) - return wake->gettime(); - return 0; -} - -void Scanner::resettime() -{ - if (wake.get()) - wake->resettime(); -} - -int Scanner::get_sleepstatus() -{ - if (wake.get()) - return wake->get_status(); - return 0; -} - -void Scanner::set_paprent(void *parent) -{ - if (parent) - m_parent = parent; -} -void Scanner::set_sleepstatus(bool off) -{ - if (wake.get()) - { - if (off) - wake->power_on(); - else - wake->power_off(); - } -} - bool Scanner::getpaperon() { +#ifdef G200 if (mb.get()) { uint val = 0; mb->read(2, val); - if ((val & 0x10000) && m_config.g200params.is_autopaper) - mb->set_auto_paper(false); return val & 0x10000; } return 0; +#endif + return 1; } void Scanner::scanpaperout() { @@ -648,7 +327,7 @@ void Scanner::scanpaperout() //LOG_TRACE(string_format("+++++paper on:%fms+++++++++++ ", swCap.elapsed_ms())); if (mb->wait_paper_out(3000)) { - HG_LOG("wait_paper_out time =%f \n",sw.elapsed_ms()); + printf("wait_paper_out time =%f \n",sw.elapsed_ms()); sw.reset(); swCap.reset(); if (data = capturer->readFrame(2000)) @@ -656,13 +335,11 @@ void Scanner::scanpaperout() printf("\n readFrame time =%f pickpapernum = %d",swCap.elapsed_ms(),pickpapernum++); if (imagehandler) { - imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++); + imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++,0x90001,CISVendor::DUNNAN_CIS_V0); data = NULL; } - //std::this_thread::sleep_for(std::chrono::milliseconds(100)); swCap.reset(); scannerinfo.RollerNum++; - scannerinfo.TotalScanned++; LOG_TRACE(string_format("capture one=%fms", swCap.elapsed_ms())); } else @@ -755,7 +432,7 @@ void Scanner::scanold() swCap.reset(); if (imagehandler) { - imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++); + imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++,0x90001,CISVendor::DUNNAN_CIS_V0); data = NULL; } LOG_TRACE(string_format("readFrame time =%f ",swCap.elapsed_ms())); diff --git a/device/gxx-linux/scanner/scanner.h b/device/gxx-linux/scanner/scanner.h index ffcd811..2afab49 100644 --- a/device/gxx-linux/scanner/scanner.h +++ b/device/gxx-linux/scanner/scanner.h @@ -1,11 +1,5 @@ #pragma once -#include -#include -#include "BlockingQueue.h" -#include "fsmstate.h" -#include -#include "commondef.h" -#include "wakeup.hpp" +#include "iscanner.h" enum MotorVersion : uint{ Motor_old, @@ -13,72 +7,25 @@ enum MotorVersion : uint{ Motor_paperout, }; -class MotorBoard; -class ICapturer; -class IImageHandler; -class Gpio; - -class Scanner +class Scanner : public IScanner { public: - Scanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake); - ~Scanner(); - void try_scan(const std::string encodehexstr); - void configparam(HGScanConfig config); - void start_scan(); - void stop_scan(); - - int count(); - int mode(); - void put(ScanEvent evt) { sysEvent.Put(evt); } - bool is_runscan(); - void set_imagehandler(std::shared_ptr handler = nullptr); - void clear_error(); - bool paper_ready(); - bool get_keeplastpaper(); - void set_motorboardcallback(MotorBoardGlue glue); - void set_imgprocparams(HGImgProcParms parmas); - void test_autocorrect(int colormode); - void test_cap(HGScanConfig config); - bool set_hgimgconfig(GScanCap config); - void add_scansever(HGIntInfo event); - void set_sleeptime(int val); - int get_sleeptime(); - void resettime(); - int get_sleepstatus(); - void set_sleepstatus(bool off); - int getimageprocedone(); - void set_paprent(void* parent); - bool getpaperon(); - int getmbstatus(); - std::string getmbversion(); + Scanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake); + virtual ~Scanner(); + virtual void start_scan() override; + virtual void stop_scan() override; + virtual int count() override; + virtual int mode() override; + virtual int getmbstatus() override; + virtual bool getpaperon() override; + virtual void runScan() override; private: - void runMessageLoop(); - void runScan(); - void startcapimage(); void scanold(); void scanpaperout(); - //std::shared_ptr testGpio; - std::thread threadRunMessageLoop; - volatile bool bMsgLoop = true; - BlockingQueue sysEvent; - - std::shared_ptr mb; - std::shared_ptr capturer; - std::shared_ptr wake; - - std::shared_ptr fu_runscan; - std::shared_ptr imagehandler; - std::function m_mtcallback; volatile int done_scan = 0; volatile bool is_ml_top = 0; volatile bool handstop = 0; - int scancount=0; - volatile unsigned int mb_error_code; + volatile int mb_error_code = 0; MotorVersion m_mbver; - HGScanConfig m_config; - GScanCap m_cap; - ScannerNativeParam scannerinfo; - void* m_parent; - std::string mbversion; + }; diff --git a/device/gxx-linux/scanner/scannero300.cpp b/device/gxx-linux/scanner/scannero300.cpp new file mode 100644 index 0000000..e4849ee --- /dev/null +++ b/device/gxx-linux/scanner/scannero300.cpp @@ -0,0 +1,293 @@ +#include +#include "Imotorboard.h" +#include "Capturer.h" +#include +#include "StopWatch.h" +#include "iimagehandler.h" +#include "applog.h" +#include "stringex.hpp" +#include "fpgacontrol.h" +#include "scannerregs.h" +#include "fpgacontrol.h" +#include "Gpio.h" +#include "scannero300.h" +#include "SysInforTool.h" +#include "correct_ultis.h" +#include "dailex.hpp" +static const std::string loggername = "ScannerO300"; +ScannerO300::ScannerO300(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake) : IScanner(capturer, mb, wake), mfpgaversion(0x90001) +{ + LOG_INIT(); + capturer->regs()->read(15, mfpgaversion); + SysInforTool(ScannerSysInfo()).GetSysInfo(); + auto mb_error_call = [&](std::uint32_t code) + { + if (done_scan) + return; + if (code == 0x40000 && m_config.g200params.paper != 16) + return; + if (code != 0) + { + imagehandler->add_scanevent({.From = MtBoard, .Code = code}); + mb_error = code; + if (code == 0x20) + scannerinfo.DoubleFeedTimes++; + done_scan = true; + } + printf("\n scan done 1 code = %d ", code); + }; + auto mb_scandone_call = [&]() + { + printf("\n scan done 2"); + done_scan = true; + }; + + auto mb_auto_paper = [&](unsigned int value) + { + printf("连续扫描模式检测到有纸"); + if (fu_runscan && fu_runscan->is_runing()) + return; + start_scan(); + }; + mb->set_callbacks({mb_error_call, mb_scandone_call, nullptr, nullptr, nullptr, mb_auto_paper}); + scannerinfo = getscannerinfo(); + + auto mb_ev_cb = [&](uint32_t ev) -> void + { + if(imagehandler) + imagehandler->add_scanevent({.From = MBEvent, .Code = ev}); + }; + mb->set_motorboard_event_callback(mb_ev_cb); +} +ScannerO300::~ScannerO300() +{ +} +void ScannerO300::start_scan() +{ + printf("m_config.g200params.color= %d ,m_config.g200params.dpi = %d ,m_config.g200params.paper = %d ", m_config.g200params.color, m_config.g200params.dpi, m_config.g200params.paper); + mb->clear_error(); + capturer->regs()->read(15, mfpgaversion); + if (m_capturereload && m_capturereload->is_runing()) + { + while (m_capturereload->is_runing()) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + m_capturereload.reset(); + } + if (fu_runscan && fu_runscan->is_runing()) + return; + if (wake.get()) + wake->setsleepfalg(true); + m_cistype = Dail().GetValue().dails.in_voltage3 == 1 ? CISVendor::DUNNAN_CIS_V0 : CISVendor::HUALIN_CIS_V0; + FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color); + capturer->open(m_config, fpgaparam); + scannerinfo = getscannerinfo(); + imagehandler->Set_ratio(fpgaparam.HRatio, fpgaparam.VRatio); + imagehandler->resetimgstatus(); + mb->clear_error(); + mb_error = 0; + scancount = 0; + fu_runscan.reset(new ThreadEx(&ScannerO300::runScan, this)); +} +void ScannerO300::stop_scan() +{ + done_scan = true; + mb->set_auto_paper(false); +} +int ScannerO300::count() +{ + return scannerinfo.RollerNum; +} +int ScannerO300::mode() +{ + return 0; +} +int ScannerO300::getmbstatus() +{ + return 0; +} +bool ScannerO300::getpaperon() +{ + return mb->paper_ready(); +} +void ScannerO300::runScan() +{ + int spdmode = 0; + if (scannerSp.find((SpeedMode)scannerinfo.speedmode) != scannerSp.end()) + spdmode = scannerSp.at((SpeedMode)scannerinfo.speedmode).motorSpeed; + mb->set_speed_mode(spdmode, m_config.g200params.dpi, m_config.g200params.color); + system("echo performance > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor"); + mb->set_double_inpect(m_config.g200params.double_feed_enbale); + mb->set_auto_paper(m_config.g200params.is_autopaper); + + StopWatch sw; + if (mb->is_converopen()) + { + imagehandler->add_scanevent({.From = MtBoard, .Code = 4}); + mb_error = 4; + printf("\n------------------converopen-------------------"); + } + else if (mb->is_jam()) + { + imagehandler->add_scanevent({.From = MtBoard, .Code = 16}); + mb_error = 16; + printf("\n------------------jam-------------------"); + } + else if (!mb->paper_ready()) + { + imagehandler->add_scanevent({.From = MtBoard, .Code = 2}); + mb_error = 2; + printf("\n-------------------no paper---------------"); + } + else + { + done_scan = false; + printf("\n------------------motor run ------------------- %f ", sw.elapsed_ms()); + std::thread m_startthread([this, spdmode] + { + std::this_thread::sleep_for(std::chrono::milliseconds(20));//20ms再启动 保证到达 wait paper in 之后才有传感器信号 + mb->set_cuospeed(0xff,m_config.g200params.dpi,m_config.g200params.color); + mb->start(); + std::this_thread::sleep_for(std::chrono::milliseconds(90)); + mb->stop_pick_paper(); + mb->set_cuospeed(spdmode,m_config.g200params.dpi,m_config.g200params.color); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + mb->pick_paper(); }); + void *data = NULL; + while (!done_scan) + { + if (mb->wait_paper_in(5000)) + { + printf("\n------------------wait_paper_in------------------- %f ", sw.elapsed_ms()); + if (mb_error != 0) + break; + capturer->snap(); + if (mb->wait_paper_out(7000)) + { + printf("\n------------------wait_paper_out------------------- %f ", sw.elapsed_ms()); + if (mb_error != 0) + break; + scannerinfo.RollerNum++; + scannerinfo.TotalScanned++; +#ifdef G300 + HGSize size; + size = papersMap[(PaperSize)m_config.g200params.paper]; + size.width = size.width == 0 ? papersMap[PaperSize::G400_A4].width : size.width; + size.height = size.height == 0 ? papersMap[PaperSize::G400_A4].height : size.height; + if (m_config.g200params.dpi != 1) + size.height = std::min((unsigned int)16002, size.height * 3 / 2); + int channels = m_config.g200params.color ? 3 : 1; + int dstwith = size.width * channels * 3; + int dstHeight = size.height / 9 * 3; +#else + int height; // + if (m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO) + { + int delaytime = m_config.g200params.dpi == 0x02 ? 150 : (m_config.g200params.dpi == 0x03 ? 250 : 100); + this_thread::sleep_for(chrono::milliseconds(delaytime)); // 纸张过了 多采集几张 + height = capturer->getautosizeheight(); + } + else + height = capturer->height(); + int channel = capturer->color() == 16 ? 3 : 1; + int dstwith = capturer->width() * 2 * 3 * channel; + int dstHeight = m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO ? height : height / channel; +#endif + printf("\n------------------readFrame------------------- %f", sw.elapsed_ms()); + if (data = capturer->readFrame(7000)) + { + printf("\n addimage %f ", sw.elapsed_ms()); + while (imagehandler->is_limit()) + { + this_thread::sleep_for(chrono::milliseconds(10)); + continue; + } + printf("\n dstwith = %d ,dstHeight = %d color type = %d", dstwith, dstHeight, capturer->color()); + imagehandler->add_image(data, dstwith, dstHeight, capturer->color(), ++scancount, mfpgaversion, m_cistype); + } + else + { + imagehandler->add_scanevent({.From = V4L2, .Code = 0}); + done_scan = true; + mb_error = 79; // 79异常取图失败 + printf("capture error \n"); + break; + } + if (imagehandler->getimgstatus().status != Error_Status::NO_error && (m_cap.is_dogeardetection || m_cap.en_sizecheck)) + { + done_scan = true; + mb_error = 82; + break; + } + if ((!mb->paper_ready()) || (scancount >= (m_cap.is_duplex ? m_cap.scannum / 2 : m_cap.scannum))) + { + done_scan = true; + break; + } + printf("\n scancount =%d m_cap.scannum =%d addimage %f", scancount, m_cap.scannum, sw.elapsed_ms()); + if (!done_scan) + mb->pick_paper(); + else + { + done_scan = true; + break; + } + printf("\n pick paper done %f ", sw.elapsed_ms()); + } + else + { + printf("\n scan done 16"); + if (mb_error == 0) + { + scannerinfo.JamTimes++; + imagehandler->add_scanevent({.From = MtBoard, .Code = 16}); + mb_error = 16; + } + break; + } + } + else + { + printf("\n scan done 8"); + imagehandler->add_scanevent({.From = MtBoard, .Code = 8}); + mb_error = 8; + scannerinfo.FeedErrorTimes++; + break; + } + } + printf("\n scan done 5"); + if (m_startthread.joinable()) + m_startthread.join(); + if ((mb_error == 0) || (mb_error == 82)) + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + mb->stop(); + } + mb->set_double_inpect(false); + m_capturereload.reset(new ThreadEx([&] + { + capturer->stop(); + capturer->close(); + capturer->reset(); })); + while (!imagehandler->done()) + this_thread::sleep_for(chrono::milliseconds(10)); + printf("-------scanner done------- %f \n", sw.elapsed_ms()); + imagehandler->add_scanevent({.From = STOPSCAN, 0}); + system("sudo cpufreq-set -g ondemand"); + if (wake.get()) + { + wake->resettime(); + wake->setsleepfalg(false); + } + savescannerinfo(scannerinfo); + done_scan = true; + if (mb_error && mb_error != 2) + { + mb->LedControlOption(HG_LedOption::HG_RED_ON, 0); + } + if (mb_error) + { + mb->set_auto_paper(false); + } + mb->set_error(mb_error); + if (!mb->paper_ready() && (mb_error == 0 || (mb->is_converopen() == false && mb->is_jam() == false && mb_error != 2))) + mb->motor_reset(); +} \ No newline at end of file diff --git a/device/gxx-linux/scanner/scannero300.h b/device/gxx-linux/scanner/scannero300.h new file mode 100644 index 0000000..62a2615 --- /dev/null +++ b/device/gxx-linux/scanner/scannero300.h @@ -0,0 +1,23 @@ +#pragma once +#include "iscanner.h" + + +class ScannerO300 : public IScanner +{ +public: + ScannerO300(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake); + virtual ~ScannerO300(); + virtual void start_scan() override; + virtual void stop_scan() override; + virtual int count() override; + virtual int mode() override; + virtual int getmbstatus() override; + virtual bool getpaperon() override; + virtual void runScan() override; +private: + volatile bool done_scan = true; + volatile int mb_error = 0; + std::uint32_t mfpgaversion; + CISVendor m_cistype; + //std::future m_addimg_future; +}; \ No newline at end of file diff --git a/device/gxx-linux/scanner/scannerregs.cpp b/device/gxx-linux/scanner/scannerregs.cpp index de49d86..0c813d8 100644 --- a/device/gxx-linux/scanner/scannerregs.cpp +++ b/device/gxx-linux/scanner/scannerregs.cpp @@ -188,7 +188,8 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) std::string cfg(load_mini_file("/root/.scanner/log/cfg_4308.bin")); GScanCap cap = *(GScanCap*)&cfg[0]; - cap.resolution_dst = cap.resolution_native = scan_dpi; + cap.resolution_dst = scan_dpi; + cap.resolution_native = 200; cap.scannum = scan_cnt; printf("DPI: %d, Count: %d\n", scan_dpi, scan_cnt); #else diff --git a/device/gxx-linux/scanner/wakeup.hpp b/device/gxx-linux/scanner/wakeup.hpp index 5c6487a..ee94a59 100644 --- a/device/gxx-linux/scanner/wakeup.hpp +++ b/device/gxx-linux/scanner/wakeup.hpp @@ -23,8 +23,7 @@ public: WakeUp() { b_run=true; - if(get_status()==0) - power_on(); + update_state(); m_thread.reset(new std::thread(&WakeUp::input,this)); m_time =std::chrono::steady_clock::now(); sleeptime = jsonconfig().getscannerinfo().sleeptime; @@ -46,7 +45,7 @@ public: return; char buf=0x55; if((m_status == 1)&&releasecallback) - releasecallback(); + releasecallback(); write(fd,&buf,1); close(fd); m_status=0; @@ -54,17 +53,23 @@ public: void power_on(){ int fd=open(dev_name,O_RDWR); + resettime(); if(fd == -1) return; char buf=0xaa; write(fd,&buf,1); close(fd); - if((m_status == 0)&&initcallback) + if((m_status == 0)&&initcallback) initcallback(); m_status=1; } int get_status() + { + return m_status; + } + + int update_state() { int fd= open(dev_name,O_RDWR); if(fd == -1) @@ -88,14 +93,14 @@ public: sleeptime= val; auto var = jsonconfig().getscannerinfo(); var.sleeptime = val; - printf("\nwakeup time %d",val); jsonconfig().savescannerinfo(var); + resettime(); } void setinitcallback(std::function init,std::function release){ this->initcallback = init; this->releasecallback = release; - } + } int gettime() {return sleeptime;} @@ -137,21 +142,33 @@ private: while (read(fd, &event, sizeof(event)) == sizeof(event)) { printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value); - if(event.type == 0x01 && event.code == 0x3e && event.value == 0x00) + if(event.type == 0x01 && event.code == 0x3e && event.value == 0x01) { - int val= get_status(); - if(val == 1) { - printf("system in sleep.\n"); - power_off(); - } - else if(val == 0) { - printf("system wakeup.\n"); - power_on(); - resettime(); - } - else { - printf("error sleep index.\n"); - } + pressed_time = std::chrono::steady_clock::now(); + } + if(event.type == 0x01 && event.code == 0x3e && event.value == 0x00) + { + + if(std::chrono::duration(std::chrono::steady_clock::now() - pressed_time).count() > 5000){ + printf("wake up poweroff .\n"); + system("poweroff"); + } + if(std::chrono::duration(std::chrono::steady_clock::now() - pressed_time).count() > 2000) + { + int val= update_state(); + if(val == 1) { + printf("system in sleep.\n"); + power_off(); + } + else if(val == 0) { + printf("system wakeup.\n"); + power_on(); + resettime(); + } + else { + printf("error sleep index.\n"); + } + } } } } @@ -164,12 +181,13 @@ private: { printf("wakeup_process.c::poll err...\n"); } - if((sleeptime!=-1) && std::chrono::duration(std::chrono::steady_clock::now()-m_time).count()>sleeptime && m_status==1 && !sleep_falg ) + if((sleeptime!=-1) && (std::chrono::duration(std::chrono::steady_clock::now()-m_time).count()>sleeptime) && (m_status==1) && (!sleep_falg) ) { - if(get_status()==1) + if(update_state()==1) power_off(); printf("\nwakeup_process sleep...\n"); } + //printf("\n wake up time ----- %f sleep_flag =%d sleeptime %d",std::chrono::duration(std::chrono::steady_clock::now()-m_time).count(),sleep_falg,sleeptime); std::this_thread::sleep_for(std::chrono::milliseconds(500)); } @@ -177,9 +195,10 @@ private: bool b_run; int sleeptime; bool sleep_falg; - std::atomic m_status; + volatile bool m_status; std::function initcallback; std::function releasecallback; std::shared_ptr m_thread; std::chrono::steady_clock::time_point m_time; + std::chrono::steady_clock::time_point pressed_time; }; \ No newline at end of file diff --git a/device/gxx-linux/scanner/xmake.lua b/device/gxx-linux/scanner/xmake.lua index 98adcf0..f33dd5c 100644 --- a/device/gxx-linux/scanner/xmake.lua +++ b/device/gxx-linux/scanner/xmake.lua @@ -4,8 +4,8 @@ target("gscanner") set_kind("static") add_files("*.cpp") add_syslinks("pthread") - -- add_links("turbojpeg") add_links("ssl","crypto") + -- add_links("turbojpeg") add_deps("motorboard", "capimage", "gusb", "gimgproc", "applog","fpgaupdate") add_packages("common") add_includedirs(".", { public = true}) \ No newline at end of file diff --git a/device/gxx-linux/scanservice/main.cpp b/device/gxx-linux/scanservice/main.cpp index 886c3d2..d5f1d85 100644 --- a/device/gxx-linux/scanservice/main.cpp +++ b/device/gxx-linux/scanservice/main.cpp @@ -1,3 +1,239 @@ +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include "filetools.h" +// #include "stringex.hpp" +// #include +// #include "usbservice.h" +// #include "Capturer.h" +// #include "motorboard.h" +// #include "itransmit.h" +// #include "scannerregs.h" +// #include "scanner.h" +// #include "inotify.h" +// #include "memoryex.h" +// #include "usbimageprocqueue.h" +// #include "imageusbtesthandler.h" +// #include "applog.h" +// #include "jsonconfig.h" +// #include "wakeup.hpp" + +// using namespace std; +// #define MY_PID_FILE "/tmp/scanservice_pid" +// #define BUF_LEN_FOR_PID 64 + +// static int write_pid_into_fd(int fd, pid_t pid) +// { +// int ret = -1; +// char buf[BUF_LEN_FOR_PID] = {0}; + +// /* Move cursor to the start of file. */ +// lseek(fd, 0, SEEK_SET); + +// sprintf(buf, "%d", pid); +// ret = write(fd, buf, strlen(buf)); +// if (ret <= 0) +// { /* Write fail or write 0 byte */ +// if (ret == -1) +// perror("Write " MY_PID_FILE " fail\n"); + +// ret = -1; +// } +// else +// { +// printf("Create " MY_PID_FILE " ok, pid=%d\n", pid); +// ret = 0; +// } + +// return ret; +// } + +// static int create_pid_file(pid_t pid) +// { +// int fd, ret; +// char buf[BUF_LEN_FOR_PID] = {0}; + +// fd = open(MY_PID_FILE, O_WRONLY | O_CREAT | O_EXCL, 0666); /* rw-rw-rw- */ +// if (fd == -1) +// { +// perror("Create " MY_PID_FILE " fail\n"); +// return -1; +// } + +// ret = flock(fd, LOCK_EX); +// if (ret == -1) +// { +// perror("flock " MY_PID_FILE " fail\n"); +// close(fd); +// return -1; +// } + +// ret = write_pid_into_fd(fd, pid); + +// flock(fd, LOCK_UN); +// close(fd); + +// return ret; +// } + +// static int check_pid_file(int fd, pid_t pid) +// { +// int ret = -1; +// pid_t old_pid; +// char buf[BUF_LEN_FOR_PID] = {0}; + +// ret = flock(fd, LOCK_EX); +// if (ret == -1) +// { +// perror("flock " MY_PID_FILE " fail\n"); +// return -1; +// } + +// ret = read(fd, buf, sizeof(buf) - 1); +// if (ret < 0) +// { /* read error */ +// perror("read from " MY_PID_FILE " fail\n"); +// ret = -1; +// } +// else if (ret > 0) +// { /* read ok */ +// old_pid = atol(buf); + +// /* Check if old_pid is running */ +// ret = kill(old_pid, 0); +// if (ret < 0) +// { +// if (errno == ESRCH) +// { /* old_pid is not running. */ +// ret = write_pid_into_fd(fd, pid); +// } +// else +// { +// perror("send signal fail\n"); +// ret = -1; +// } +// } +// else +// { /* running */ +// printf("Program already exists, pid=%d\n", old_pid); +// ret = -1; +// } +// } +// else if (ret == 0) +// { /* read 0 byte from file */ +// ret = write_pid_into_fd(fd, pid); +// } + +// flock(fd, LOCK_UN); + +// return ret; +// } + +// static int init_pid_file() +// { +// pid_t pid; +// int fd, ret; + +// pid = getpid(); + +// fd = open(MY_PID_FILE, O_RDWR); +// if (fd == -1) +// { /* open file fail */ +// if (errno == ENOENT) +// { /* No such file. Create one for this program. */ +// ret = create_pid_file(pid); +// } +// else +// { +// perror("open " MY_PID_FILE " fail\n"); +// ret = -1; +// } +// } +// else +// { /* pid file already exists */ +// ret = check_pid_file(fd, pid); +// close(fd); +// } + +// return ret; +// } + + + +// static void sigHandler(int sig) +// { +// if (sig == SIGINT || sig == SIGTERM) +// remove(MY_PID_FILE); +// printf("exit now \n"); +// _exit(0); +// } + + +// int main() +// { + +// if (-1 == init_pid_file()) +// { +// exit(-1); +// } + +// /* Ctrl + C */ +// if (signal(SIGINT, sigHandler) == SIG_ERR) +// { +// exit(-1); +// } + +// /* kill pid / killall name */ +// if (signal(SIGTERM, sigHandler) == SIG_ERR) +// { +// exit(-1); +// } +// auto wake = std::shared_ptr(new WakeUp()); +// auto cap = std::shared_ptr(new Capturer()); +// auto mt = std::shared_ptr(new MotorBoard()); + +// wake->setinitcallback([&mt,&cap]{ +// std::this_thread::sleep_for(std::chrono::milliseconds(5000)); +// cap->Fpga_regsAccess_reset(true); +// mt->init_statecontrol(); +// },[&mt,&cap]{ +// cap->Fpga_regsAccess_reset(false); +// mt->release_statecontrol(); +// }); +// auto scanner = std::shared_ptr(new Scanner(cap, mt,wake)); +// UsbService us(cap->regs(), mt->regs()); +// auto usbhotplugcall = [&](bool connect){ +// if(connect){ +// printf("USB Connect\n"); +// }else +// { +// scanner->stop_scan(); +// printf("USB Disconnect Scanner STOP SCAN\n"); +// exit(0); +// } + +// }; +// us.set_onconnect_call(usbhotplugcall); +// auto notify = us.notify(); + +// std::shared_ptr usbImage(new UsbImageProcQueue(notify)); +// auto transfer = us.transmiter(); +// auto receiver = us.receiver(); +// std::shared_ptr regs = std::shared_ptr(new ScannerRegAccess(scanner, usbImage, transfer,receiver)); +// scanner->set_imagehandler(std::shared_ptr(new ImageUsbHandler(usbImage))); +// us.set_scannerregs(regs); +// while(1) {std::this_thread::sleep_for(std::chrono::milliseconds(2));} +// return 0; +// } + #include #include #include @@ -10,10 +246,14 @@ #include #include #include "filetools.h" -#include "stringex.hpp" #include #include "usbservice.h" #include "Capturer.h" +#include "Imotorboard.h" +#include "motormanager.h" +#include "iscanner.h" +#include "scannero300.h" +#include "MonoCapturer.h" #include "motorboard.h" #include "itransmit.h" #include "scannerregs.h" @@ -25,6 +265,8 @@ #include "applog.h" #include "jsonconfig.h" #include "wakeup.hpp" +#include "Led.h" +#include "dailex.hpp" using namespace std; #define MY_PID_FILE "/tmp/scanservice_pid" @@ -196,35 +438,59 @@ int main() { exit(-1); } + //auto deviceinfo = jsonconfig().getdeviceinfo(); auto wake = std::shared_ptr(new WakeUp()); - auto cap = std::shared_ptr(new Capturer()); - auto mt = std::shared_ptr(new MotorBoard()); - - wake->setinitcallback([&mt,&cap]{ - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); - cap->Fpga_regsAccess_reset(true); - mt->init_statecontrol(); - },[&mt,&cap]{ - cap->Fpga_regsAccess_reset(false); - mt->release_statecontrol(); - }); - auto scanner = std::shared_ptr(new Scanner(cap, mt,wake)); + //auto cap = std::shared_ptr(new Capturer()); + auto cap = std::shared_ptr(new MonoCapturer()); + std::shared_ptr mt; + std::shared_ptr scanner; + mt = std::shared_ptr(new MotorManager()); + scanner = std::shared_ptr(new ScannerO300(cap, mt,wake)); + mt->GetOrSetSleepFlag(false,wake->get_status() == 0 ?true : false); + printf("\n Scan_G300"); + printf("\n 鎷ㄧ爜寮€鍏?%d",Dail().GetValue().value); UsbService us(cap->regs(), mt->regs()); auto usbhotplugcall = [&](bool connect){ if(connect){ printf("USB Connect\n"); + mt->GetOrSetUsbConnectFlag(false,true); }else { scanner->stop_scan(); + StopWatch sw; + while(scanner->is_runscan() || sw.elapsed_s() < 10) + { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + mt->GetOrSetUsbConnectFlag(false,false); printf("USB Disconnect Scanner STOP SCAN\n"); exit(0); } }; + us.set_onconnect_call(usbhotplugcall); auto notify = us.notify(); - std::shared_ptr usbImage(new UsbImageProcQueue(notify)); + wake->setinitcallback([&cap,&mt]{ + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + cap->Fpga_regsAccess_reset(true); + mt->LedControlOption(HG_LedOption::HG_WHITE_ON,0); + mt->GetOrSetSleepFlag(false,false); + },[&mt,&cap,&usbImage,&scanner]{ + scanner->stop_scan(); + scanner->add_scansever({.From = STOPSCAN , .Code = 1}); + cap->Fpga_regsAccess_reset(false); + mt->LedControlOption(HG_LedOption::HG_GREEN_ON,0); + mt->GetOrSetSleepFlag(false,true); + + }); + if(wake->get_status() == 0) + { + cap->Fpga_regsAccess_reset(false); + mt->LedControlOption(HG_LedOption::HG_GREEN_ON,0); + mt->GetOrSetSleepFlag(false,true); + } auto transfer = us.transmiter(); auto receiver = us.receiver(); std::shared_ptr regs = std::shared_ptr(new ScannerRegAccess(scanner, usbImage, transfer,receiver)); diff --git a/device/gxx-linux/testcapimage/main.cpp b/device/gxx-linux/testcapimage/main.cpp index a81562a..b92c5a3 100644 --- a/device/gxx-linux/testcapimage/main.cpp +++ b/device/gxx-linux/testcapimage/main.cpp @@ -121,7 +121,8 @@ int main() config.g200params.dpi=1; config.g200params.paper=(unsigned int)PaperSize::G400_A4; void *data; - cap->open(config); + // cap->open(config); + cap->open(); int ch = 0; int ixx = 0; diff --git a/device/gxx-linux/testimgproc/main.cpp b/device/gxx-linux/testimgproc/main.cpp index 8a136ca..e49f495 100644 --- a/device/gxx-linux/testimgproc/main.cpp +++ b/device/gxx-linux/testimgproc/main.cpp @@ -26,9 +26,16 @@ int main() //std::string straa = read_all_from("/mnt/d/3.tif"); //fipMemoryIO mio((unsigned char*)straa.c_str(), straa.size()); //auto filet = mio.getFileType(); - std::string imgpath = "/home/linaro/gxx-linux/2.jpg"; - cv::Mat mat=cv::imread(imgpath,cv::IMREAD_GRAYSCALE); - ImageEncodePtr encoder(new BmpImageEncode()); - encoder->encode(mat); + std::string imgpath = "/root/.scanner/log/raw.bmp"; + cv::Mat mat=cv::imread(imgpath,cv::IMREAD_COLOR); + if(mat.empty()) + { + std::cout<<" empty image "< buffer; + cv::imencode(".jpg", mat,buffer); + std::cout<<" imencode image done"< lck(mx); if(images.size()>0) { + printf("UsbImageProcQueue::pop\n"); auto front = images.front(); images.pop(); //auto front=images.Take(); diff --git a/device/gxx-linux/usb/src/common/packet.h b/device/gxx-linux/usb/src/common/packet.h index 839abd0..c30b7bd 100644 --- a/device/gxx-linux/usb/src/common/packet.h +++ b/device/gxx-linux/usb/src/common/packet.h @@ -82,6 +82,7 @@ enum packet_cmd PACK_CMD_SCAN_BASE = 200, PAIR_COMMAND(PACK_CMD_SCAN_START), // start scanning, [in]: PACK_BASE, [out]: PACK_BASE PAIR_COMMAND(PACK_CMD_SCAN_IMG), // device -> host, PACK_BASE::payload - LPPACKIMAGE + PAIR_COMMAND(PACK_CMD_SCAN_PAPER), // device -> host, ONE paper has passed through the CIS. PACK_BASE::data - status of this paper PACK_CMD_SCAN_FINISHED_ROGER, // device -> host, PACK_BASE::data is scanner_status PAIR_COMMAND(PACK_CMD_SCAN_STOP), // stop scanning, [in]: PACK_BASE, [out]: PACK_BASE //PAIR_COMMAND(PACK_CMD_SCAN_IMAGE_REQ), // get image request, [in]: PACK_BASE, [out] PACK_BASE on error, or PACK_BASE::payload - LPPACKIMAGE @@ -155,12 +156,13 @@ enum img_compression }; enum img_status { - IMG_STATUS_OK = 0, - IMG_STATUS_DOUBLE, - IMG_STATUS_JAM, + IMG_STATUS_OK = 0, // normal + IMG_STATUS_DOUBLE, // double-feeded paper + IMG_STATUS_JAM, // jammed paper IMG_STATUS_STAPLE, // staples on the paper IMG_STATUS_SIZE_ERR, // size check failed IMG_STATUS_DOGEAR, // paper has dogear + IMG_STATUS_BLANK, // blank image }; enum data_type { @@ -190,6 +192,16 @@ enum rot_angle ROT_ANGLE_180, ROT_ANGLE_270, }; +enum clr_channel +{ + COLOR_CHANNEL_RGB = 0, + COLOR_CHANNEL_RGBA, + COLOR_CHANNEL_GRAY, + COLOR_CHANNEL_RED, + COLOR_CHANNEL_GREEN, + COLOR_CHANNEL_BLUE, + COLOR_CHANNEL_ALPHA, +}; #pragma pack(push) #pragma pack(1) @@ -251,7 +263,7 @@ typedef struct _img_pos uint64_t img_over : 1; // 0 - has data yet; 1 - END for the image. (image-collector set) uint64_t paper_side : 3; // enum paper_side. front of paper(When scanning multiple sheets, the paper feeding side is the front side). (image-collector set) uint64_t back_rot : 2; // back rotation angle, enum rot_angle. (image-collector set) - uint64_t channel_ind : 4; // index of color channel, based ZERO, 0x0f for all channels. (image-collector set) + uint64_t channel_ind : 4; // index of color channel, enum clr_channel. (image-collector set) uint64_t status : 4; // img_status. (image-collector set) uint64_t split_ind : 7; // splitting order, from left to right and then top to bottom, based ZERO uint64_t multiout_ind : 4; // index of multi-out @@ -274,7 +286,7 @@ typedef struct _pack_img uint32_t reserve : 2; // unused now uint32_t info_size; // image information size in bytes, information part is used for quality of JPEG, pallete of BMP .... (image-collector set) uint64_t data_size; // image data size in 'data' with bytes. (image-collector set) - char data[0]; // two parts: image info (info_size) + image data (data_size) +// char data[0]; // two parts: image info (info_size) + image data (data_size) STRUCT_CONSTRUCTOR(_pack_img) }PACKIMAGE, * LPPACKIMAGE; diff --git a/device/gxx-linux/usb/src/common/sane_cfg.cpp b/device/gxx-linux/usb/src/common/sane_cfg.cpp index 45174e9..b84c9a3 100644 --- a/device/gxx-linux/usb/src/common/sane_cfg.cpp +++ b/device/gxx-linux/usb/src/common/sane_cfg.cpp @@ -102,7 +102,44 @@ bool sane_cfg_provider::sane_option_value_set(json* jsn, void* data, const char* return ret; } +int32_t sane_cfg_provider::inner_get_config(json* root, void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + int ret = 0; + std::string val(""); + if (!len) + return EINVAL; + + if (cfg_name) + { + json* child = nullptr; + if (root->get_value(cfg_name, child) && child) + { + val = sane_cfg_provider::sane_option_value_get(child, "cur", strval); + child->release(); + } + } + else + { + val = root->to_string(); + } + + if (ret == 0) + { + if (*len < val.length()) + { + *len = val.length() + 4; + ret = ENOMEM; + } + else + { + memcpy(buf, val.c_str(), val.length()); + *len = val.length(); + } + } + + return ret; +} diff --git a/device/gxx-linux/usb/src/common/sane_cfg.h b/device/gxx-linux/usb/src/common/sane_cfg.h index 31ceab6..5ba98fc 100644 --- a/device/gxx-linux/usb/src/common/sane_cfg.h +++ b/device/gxx-linux/usb/src/common/sane_cfg.h @@ -46,6 +46,9 @@ public: static std::string sane_option_value_get(json* jsn, const char* key = "cur"/*cur, default*/, std::string* strval = nullptr/*convert value into string*/); static bool sane_option_value_set(json* jsn, void* data, const char* key = "cur"/*cur, default*/); +protected: + int32_t inner_get_config(json* root, void* buf, size_t* len, const char* cfg_name, std::string* strval); + public: // Function: get all or given name configuration value // @@ -116,19 +119,6 @@ public: int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo); }; -class hardware : public sane_cfg_provider -{ -public: - hardware(); - -protected: - ~hardware(); - -public: - virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* str = nullptr) override; - virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; -}; - class img_processor : public sane_cfg_provider diff --git a/device/gxx-linux/usb/src/hardware/hardware.cpp b/device/gxx-linux/usb/src/hardware/hardware.cpp new file mode 100644 index 0000000..074583a --- /dev/null +++ b/device/gxx-linux/usb/src/hardware/hardware.cpp @@ -0,0 +1,432 @@ +#include "hardware.h" + +#include +//{ +// "cis-mode": { +// "category": "base", +// "readonly" : false, +// "affect" : 2, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "CIS����ģʽ", +// "desc" : "����CIS��ɫ���߻ҶȵĹ���ģʽ", +// "type" : "string", +// "cur" : "��ɫ", +// "default" : "��ɫ", +// "size" : 12, +// "range": ["��ɫ", "�Ҷ�"] +// }, +// "cis-dpi": { +// "category": "base", +// "readonly" : false, +// "affect" : 2, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "CIS�ֱ���", +// "desc" : "����CIS�ɼ��ķֱ���", +// "type" : "int", +// "cur" : 200, +// "default" : 200, +// "size" : 4, +// "range": [200, 300] +// }, +// "cis-sample": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "CIS����Ƶ��", +// "desc" : "����CIS��ͷ�����Ĺ���Ƶ��", +// "type" : "int", +// "cur" : 256, +// "default" : 256, +// "size" : 4, +// "range": [128, 256, 512] +// }, +// "frame-h": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "CIS֡�߶�", +// "desc" : "����CISÿһ֡�ĸ߶�", +// "type" : "int", +// "cur" : 12, +// "default" : 12, +// "size" : 4, +// "range": [4, 8, 12, 16] +// }, +// "gain-front": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "��������", +// "desc" : "����CIS���澵ͷ������", +// "type" : "int", +// "cur" : 256, +// "default" : 256, +// "size" : 4, +// "range": [100, 200, 300, 600] +// }, +// "gain-back": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "��������", +// "desc" : "����CIS���澵ͷ������", +// "type" : "int", +// "cur" : 256, +// "default" : 256, +// "size" : 4, +// "range": [100, 200, 300, 600] +// }, +// "offset-front": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "����ƫ��", +// "desc" : "����CIS�����ƫ�ƾ���", +// "type" : "int", +// "cur" : 150, +// "default" : 150, +// "size" : 4, +// "range": [0, 50, 100, 150, 200] +// }, +// "offset-back": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "����ƫ��", +// "desc" : "����CIS�����ƫ�ƾ���", +// "type" : "int", +// "cur" : 150, +// "default" : 150, +// "size" : 4, +// "range": [0, 50, 100, 150, 200] +// }, +// "exposure-f-r": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "�����ɫ�����ع��", +// "desc" : "���������ɫ�������ع�ǿ��", +// "type" : "int", +// "cur" : 0, +// "default" : 0, +// "size" : 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-f-g": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "������ɫ�����ع��", +// "desc" : "����������ɫ�������ع�ǿ��", +// "type" : "int", +// "cur" : 0, +// "default" : 0, +// "size" : 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-f-b": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "������ɫ�����ع��", +// "desc" : "����������ɫ�������ع�ǿ��", +// "type" : "int", +// "cur" : 0, +// "default" : 0, +// "size" : 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-b-r": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "�����ɫ�����ع��", +// "desc" : "�����������ɫ�������ع�ǿ��", +// "type" : "int", +// "cur" : 0, +// "default" : 0, +// "size" : 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-b-g": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "������ɫ�����ع��", +// "desc" : "���ñ�����ɫ�������ع�ǿ��", +// "type" : "int", +// "cur" : 0, +// "default" : 0, +// "size" : 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-b-b": { +// "category": "base", +// "readonly" : false, +// "affect" : 0, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "pos" : 0, +// "unit" : "None", +// "title" : "������ɫ�����ع��", +// "desc" : "���ñ�����ɫ�������ع�ǿ��", +// "type" : "int", +// "cur" : 0, +// "default" : 0, +// "size" : 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +//} +static std::string json_text = + "{\"cis-mode\":{\"category\":\"base\",\"readonly\":false,\"affect\":2,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u5de5\\u4f5c\\u6a21\\u5f0f\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u5f69\\u8272\\u6216\\u8005\\u7070\\u5ea6\\u7684\\u5de5\\u4f5c\\u6a21\\u5f0f\",\"type\":\"string\",\"cur\":\"\\u5f69\\u8272\",\"default\":\"\\u5f69\\u8272\",\"size\":12,\"range\":[\"\\u5f69\\u8272\",\"\\u7070\\u5ea6\"]},\"cis-dpi\":{\"category\":\"base\",\"readonly\":false,\"affect\":2,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u91c7\\u96c6\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[200,300]},\"cis-sample\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u91c7\\u6837\\u9891\\u7387\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u955c\\u5934\\u91c7\\u6837\\u7684\\u5de5\\u4f5c\\u9891\\u7387\",\"type\":\"int\",\"cur\":256,\"default\":256,\"size\":4,\"range\":[128,256,512]},\"frame-h\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u5e27\\u9ad8\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u6bcf\\u4e00\\u5e27\\u7684\\u9ad8\\u5ea6\",\"type\":\"int\",\"cur\":12,\"default\":12,\"size\":4,\"range\":[4,8,12,16]},\"gain-front\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u589e\\u76ca\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u6b63\\u9762\\u955c\\u5934\\u7684\\u589e\\u76ca\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[100,200,300,600]},\"gain-back\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u589e\\u76ca\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u80cc\\u9762\\u955c\\u5934\\u7684\\u589e\\u76ca\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[100,200,300,600]},\"offset-front\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u504f\\u79fb\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u6b63\\u9762\\u7684\\u504f\\u79fb\\u8ddd\\u79bb\",\"type\":\"int\",\"cur\":150,\"default\":150,\"size\":4,\"range\":[0,50,100,150,200]},\"offset-back\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u504f\\u79fb\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u80cc\\u9762\\u7684\\u504f\\u79fb\\u8ddd\\u79bb\",\"type\":\"int\",\"cur\":150,\"default\":150,\"size\":4,\"range\":[0,50,100,150,200]},\"exposure-f-r\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-f-g\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-f-b\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-b-r\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u80cc\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-b-g\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u80cc\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-b-b\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u80cc\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}}}"; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class hardware +hardware::hardware() : cfg_(new json()) +{ + printf("parse hardware json: %s\n", cfg_->attach_text(&json_text[0]) ? "OK" : "Failed"); + memset(&api_, 0, sizeof(api_)); +} +hardware::~hardware() +{ + cfg_->release(); +} + +int32_t hardware::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + return inner_get_config(cfg_, buf, len, cfg_name, strval); +} +int32_t hardware::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + int ret = ENOENT; + json* child = nullptr; + + if (cfg_->get_value(cfg_name, child) && child) + { + ret = set(cfg_name, data, len); + if (ret == 0 || ret == EUCLEAN) + { + sane_option_value_set(child, data); + if (afterdo) + { + child->get_value("affect", ret); + *afterdo = ret; + ret = 0; + } + } + child->release(); + } + + return ret; +} + +void hardware::set_api(LPCISAPI api) +{ + memset(&api_, 0, sizeof(api_)); + if (api) + memcpy(&api_, api, sizeof(api_)); +} + +int32_t hardware::set(const char* name, void* data, size_t* len) +{ + int32_t ret = ENOENT; + int val = *(int*)data; + std::string n(name); + CIS_API api = CIS_API(); + + if (n == "cis-mode") + { + int clr = 1; + std::string gray("\xE7\x81\xB0\xE5\xBA\xA6"), + color("\xE5\xBD\xA9\xE8\x89\xB2"); + + n = std::string((char*)data); + if (n == gray) // �Ҷ� + { + clr = 0; + } + else + { + if (n != color) + { + ret = EUCLEAN; + strcpy((char*)data, color.c_str()); + *len = color.length(); + } + } + + val = clr; + if (api_.set_color_mode) + { + ret = 0; + api_.set_color_mode(&val); + if (val != clr) + { + if (val == 0) + { + strcpy((char*)data, gray.c_str()); + *len = gray.length(); + } + else + { + strcpy((char*)data, color.c_str()); + *len = color.length(); + } + ret = EUCLEAN; + } + } + } + else if (n == "cis-dpi") + { + api = api_.set_dpi; + } + else if (n == "cis-sample") + { + api = api_.set_sample; + } + else if (n == "frame-h") + { + api = api_.set_frame_height; + } + else if (n == "gain-front") + { + api = api_.set_gain_front; + } + else if (n == "gain-back") + { + api = api_.set_gain_back; + } + else if (n == "offset-front") + { + api = api_.set_offset_front; + } + else if (n == "offset-back") + { + api = api_.set_offset_back; + } + else if (n == "exposure-f-r") + { + api = api_.set_exposure_front_red; + } + else if (n == "exposure-f-g") + { + api = api_.set_exposure_front_green; + } + else if (n == "exposure-f-b") + { + api = api_.set_exposure_front_blue; + } + else if (n == "exposure-b-r") + { + api = api_.set_exposure_back_red; + } + else if (n == "exposure-b-g") + { + api = api_.set_exposure_back_green; + } + else if (n == "exposure-b-b") + { + api = api_.set_exposure_back_blue; + } + + if (api) + { + ret = 0; + api(&val); + if (val != *(int*)data) + { + *(int*)data = val; + ret = EUCLEAN; + } + } + + return ret; +} diff --git a/device/gxx-linux/usb/src/hardware/hardware.h b/device/gxx-linux/usb/src/hardware/hardware.h new file mode 100644 index 0000000..a257def --- /dev/null +++ b/device/gxx-linux/usb/src/hardware/hardware.h @@ -0,0 +1,56 @@ +#pragma once + +// image process interface classes +// +// created on 2023-04-19 +// + +#include +#include +#include +#include + +class json; + +#define CIS_API std::function // return error code, set real value to parameter if in-value was not exact + +typedef struct _cis_api +{ + CIS_API set_color_mode; + CIS_API set_dpi; + CIS_API set_sample; + CIS_API set_frame_height; + CIS_API set_gain_front; + CIS_API set_gain_back; + CIS_API set_offset_front; + CIS_API set_offset_back; + CIS_API set_exposure_front_red; + CIS_API set_exposure_front_green; + CIS_API set_exposure_front_blue; + CIS_API set_exposure_back_red; + CIS_API set_exposure_back_green; + CIS_API set_exposure_back_blue; +}CISAPI, *LPCISAPI; + +class hardware : public sane_cfg_provider +{ + json* cfg_; + CISAPI api_; + + int32_t set(const char* name, void* data, size_t* len); + +public: + hardware(); + +protected: + ~hardware(); + + // sane_cfg_provider +public: + virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; + virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; + +public: + void set_api(LPCISAPI api); +}; + diff --git a/device/gxx-linux/usb/src/usbdevice.cpp b/device/gxx-linux/usb/src/usbdevice.cpp index 4bbc0fe..990beb2 100644 --- a/device/gxx-linux/usb/src/usbdevice.cpp +++ b/device/gxx-linux/usb/src/usbdevice.cpp @@ -15,6 +15,7 @@ #ifdef ASYNC_EP #include "common/sys_util.h" #include "common/json/json.h" +#include "hardware/hardware.h" #include "commondef.h" #endif @@ -1558,6 +1559,7 @@ protected: virtual ~image_packet() { uint32_t size = img_->size(); + head_->release(); img_.reset(); log_cls::log(LOG_LEVEL_ALL, "Image-%04u sending complete: %u/%u, memory usage %s\n", ind_, offset_, size, sys_util::format_readable_bytes(sys_util::get_memory_usage("scan")).c_str()); @@ -1726,7 +1728,7 @@ dyn_mem_ptr UsbDevice::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_ cfg->val_off = 0; cfg->name_off = val.length() + 1; pk->payload_len = sizeof(CFGVAL) + strlen(pack->payload) + 1 + val.length() + 1; - strcpy(cfg->data, val.c_str()); + memcpy(cfg->data, val.c_str(), val.length()); strcpy(cfg->data + cfg->name_off, pack->payload); reply->set_len(base_head_size + pk->payload_len); *used = base_head_size + pack->payload_len; @@ -1903,6 +1905,8 @@ void UsbDevice::do_system_command(const char* cmd) void UsbDevice::init(void) { readonly_cfg* r = new readonly_cfg(); + hardware *hrd = new hardware(); + size_t l = sizeof(dpi_); cfg_text_ = "{\"resolution\":{\"category\":\"base\",\"readonly\":false,\"affect\":2,\"ver\":1,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[100,150,200,300,600]},\"count\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"ver\":1,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u7684\\u7eb8\\u5f20\\u6570\\u91cf\",\"type\":\"int\",\"cur\":-1,\"default\":-1,\"size\":4,\"range\":[-1,1]}}"; @@ -1912,6 +1916,8 @@ void UsbDevice::init(void) cfg_ = new sane_cfg_mgr(); cfg_->reg_sane_provider(dynamic_cast(r)); l = cfg_->reg_sane_provider(dynamic_cast(this)); + l = cfg_->reg_sane_provider(dynamic_cast(hrd)); + hrd->release(); r->release(); } void UsbDevice::save_image(MemoryPtr data, bool img) @@ -1942,7 +1948,7 @@ void UsbDevice::save_image(MemoryPtr data, bool img) } } } - else + else if(data) { HGIntInfo* info = (HGIntInfo*)data->data(); dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE)); @@ -2035,6 +2041,15 @@ void UsbDevice::save_image(MemoryPtr data, bool img) } reply->release(); } + else + { + // paper count ... + dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE)); + BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_SCAN_PAPER_ROGER, 0, 0); + reply->set_len(sizeof(PACK_BASE)); + usb_->write_bulk(reply); + reply->release(); + } } int32_t UsbDevice::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) @@ -2049,25 +2064,26 @@ int32_t UsbDevice::get_config(void* buf, size_t* len, const char* cfg_name, std: json *jsn = new json(); if(jsn->attach_text(&cfg_text_[0])) { - json* child = nullptr; + ret = inner_get_config(jsn, buf, len, cfg_name, strval); + // json* child = nullptr; - ret = ENOENT; - if(jsn->get_value(cfg_name, child) && child) - { - std::string val(sane_cfg_provider::sane_option_value_get(child, "cur", strval)); - child->release(); + // ret = ENOENT; + // if(jsn->get_value(cfg_name, child) && child) + // { + // std::string val(sane_cfg_provider::sane_option_value_get(child, "cur", strval)); + // child->release(); - if(*len < val.length()) - { - *len = val.length(); - ret = ENOMEM; - } - else - { - memcpy(buf, val.c_str(), val.length()); - *len = val.length(); - } - } + // if(*len < val.length()) + // { + // *len = val.length(); + // ret = ENOMEM; + // } + // else + // { + // memcpy(buf, val.c_str(), val.length()); + // *len = val.length(); + // } + // } jsn->release(); } } diff --git a/device/gxx-linux/usb/xmake.lua b/device/gxx-linux/usb/xmake.lua index 92a8321..b487997 100644 --- a/device/gxx-linux/usb/xmake.lua +++ b/device/gxx-linux/usb/xmake.lua @@ -3,7 +3,7 @@ add_rules("mode.debug", "mode.release") target("gusb") set_kind("static") add_syslinks("pthread") - add_files("*.cpp", "src/*.cpp", "src/common/*.cpp", "src/common/json/*.c*") + add_files("*.cpp", "src/*.cpp", "src/common/*.cpp", "src/common/json/*.c*", "src/hardware/*.cpp") add_includedirs("inc") add_includedirs("src/common") add_includedirs(".", { public = true}) diff --git a/device/gxx-linux/xmake.lua b/device/gxx-linux/xmake.lua index 179f1d6..dd76911 100644 --- a/device/gxx-linux/xmake.lua +++ b/device/gxx-linux/xmake.lua @@ -66,7 +66,7 @@ target("conf") add_includedirs("$(buildir)/config/header", { public = true }) target_end("conf") -includes("regs", "deviceio", "motorboard", "capimage", "usb", "service", "scanner", "imgproc", "applog","scanservice","fpgaupdate") +includes("regs", "deviceio", "motor_run", "motorboard", "capimage", "usb", "service", "scanner", "imgproc", "applog","scanservice","fpgaupdate") add_includedirs("/usr/local/include/opencv4", "imgproc/ImageProcess") add_linkdirs("/usr/local/lib/") diff --git a/pc/code_twain/device/scanner.vcxproj b/pc/code_twain/device/scanner.vcxproj index 4260684..d2644e4 100644 --- a/pc/code_twain/device/scanner.vcxproj +++ b/pc/code_twain/device/scanner.vcxproj @@ -102,7 +102,7 @@ Level3 true - WIN32;HGSCANNER_EXPORT;CUSTOM_USBVIEW;_DIRECT_BUILD;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;OEM_NONE;HGSCANNER_EXPORT;CUSTOM_USBVIEW;_DIRECT_BUILD;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true 4996 MultiThreadedDebug diff --git a/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe b/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe index f5d34e4..16c2333 100644 Binary files a/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe and b/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe differ diff --git a/pc/code_twain/sln/usb_tools/DlgScanner.cpp b/pc/code_twain/sln/usb_tools/DlgScanner.cpp index 9381e24..6520473 100644 --- a/pc/code_twain/sln/usb_tools/DlgScanner.cpp +++ b/pc/code_twain/sln/usb_tools/DlgScanner.cpp @@ -630,7 +630,7 @@ IMPLEMENT_DYNAMIC(CDlgScanner, CDialogEx) CDlgScanner::CDlgScanner(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_SCANNER, pParent) , scanner_(NULL), auto_tx_file_(-1), auto_tx_(false) - , setting_ui_(NULL), img_cnt_(0) + , setting_ui_(NULL), img_cnt_(0), paper_cnt_(0) { g_my_inst = GetModuleHandle(NULL); @@ -695,10 +695,10 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp) if (err) //::SetDlgItemTextW(m_hWnd, IDC_EDIT_COUNT, (L"Receive image " + std::to_wstring(img_cnt_) + L" error: " + std::to_wstring(err)).c_str()); - dlg->set_text(IDC_EDIT_COUNT, (L"Receive image " + std::to_wstring(img_cnt_) + L" error: " + std::to_wstring(err)).c_str()); + dlg->set_text(IDC_EDIT_COUNT, (L"Receive image " + (std::to_wstring(dlg->img_cnt_) + L"/" + std::to_wstring(dlg->paper_cnt_)) + L" error: " + std::to_wstring(err)).c_str()); else if (cur >= total) { - dlg->set_text(IDC_EDIT_COUNT, std::to_wstring(dlg->img_cnt_).c_str()); + dlg->set_text(IDC_EDIT_COUNT, (std::to_wstring(dlg->img_cnt_) + L"/" + std::to_wstring(dlg->paper_cnt_)).c_str()); if (dlg->is_checked(IDC_CHECK_AUTO_OPEN_IMG)) ShellExecuteA(dlg->m_hWnd, "Open", cur_img_file.c_str(), NULL, NULL, SW_SHOWNORMAL); @@ -708,7 +708,33 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp) }; auto img_keeper = [&](LPPACKIMAGE img, uint64_t size) -> data_holder_ptr { - if (img) + if (img == IMG_RECEIVER_FINISHED) + { + // scan stopped ... + wchar_t buf[40] = { 0 }; + HWND wnd = GetDlgItem(IDC_EDIT_COUNT)->m_hWnd; + HDC dc = ::GetDC(wnd); + + set_text(IDC_BUTTON_SCAN, L"Scan"); + ::SetTextColor(dc, size ? RGB(255, 0, 0) : RGB(0, 0, 0)); + ::ReleaseDC(wnd, dc); + + log_cls::log(LOG_LEVEL_DEBUG, "Scan stopped with error %s\r\n", usb::u2a(scanner_status(size, buf)).c_str()); + + set_text(IDC_EDIT_COUNT, (std::to_wstring(img_cnt_) + L"/" + std::to_wstring(paper_cnt_)).c_str()); + if (size == 0) + size = SCANNER_STATUS_READY; + ::PostMessage(m_hWnd, WM_DEVICE_STATTUS, 0, (LPARAM)size); + + return NULL; + } + else if (img == IMG_RECEIVER_PAPER_CNT) + { + set_text(IDC_EDIT_COUNT, (std::to_wstring(img_cnt_) + L"/" + std::to_wstring(++paper_cnt_)).c_str()); + + return NULL; + } + else { file_saver* saver = new file_saver(); std::string root(usb::u2a(img_root_.c_str())); @@ -731,26 +757,6 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp) return dynamic_cast(saver); } - else - { - // scan stopped ... - wchar_t buf[40] = { 0 }; - HWND wnd = GetDlgItem(IDC_EDIT_COUNT)->m_hWnd; - HDC dc = ::GetDC(wnd); - - set_text(IDC_BUTTON_SCAN, L"Scan"); - ::SetTextColor(dc, size ? RGB(255, 0, 0) : RGB(0, 0, 0)); - ::ReleaseDC(wnd, dc); - - log_cls::log(LOG_LEVEL_DEBUG, "Scan stopped with error %s\r\n", usb::u2a(scanner_status(size, buf)).c_str()); - - set_text(IDC_EDIT_COUNT, std::to_wstring(img_cnt_).c_str()); - if (size == 0) - size = SCANNER_STATUS_READY; - ::PostMessage(m_hWnd, WM_DEVICE_STATTUS, 0, (LPARAM)size); - - return NULL; - } }; auto status_cb = [&](uint32_t status) -> void { @@ -1198,6 +1204,7 @@ void CDlgScanner::OnBnClickedButtonScan() if (wcsicmp(title, L"Scan") == 0) { img_cnt_ = 0; + paper_cnt_ = 0; SetDlgItemInt(IDC_EDIT_COUNT, img_cnt_); if (scanner_) { diff --git a/pc/code_twain/sln/usb_tools/DlgScanner.h b/pc/code_twain/sln/usb_tools/DlgScanner.h index 0c1dc1d..965e46f 100644 --- a/pc/code_twain/sln/usb_tools/DlgScanner.h +++ b/pc/code_twain/sln/usb_tools/DlgScanner.h @@ -59,6 +59,7 @@ class CDlgScanner : public CDialogEx SANEAPI sane_api_; std::wstring img_root_; uint32_t img_cnt_; + uint32_t paper_cnt_; public: CDlgScanner(CWnd* pParent = nullptr); // 标准构造函数 diff --git a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp index b9d0789..b681a2d 100644 --- a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp +++ b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp @@ -191,11 +191,21 @@ scanner_handler::scanner_handler(void) : usb_(nullptr), status_(SCANNER_STATUS_N *more = dynamic_cast(receiver); } } + else if (pack->cmd == PACK_CMD_SCAN_PAPER_ROGER) + { + if (img_receiver_) + { + data_holder_ptr receiver = img_receiver_(IMG_RECEIVER_PAPER_CNT, pack->data); + if (receiver) + receiver->release(); + } + *used = sizeof(PACK_BASE); + } else if (pack->cmd == PACK_CMD_SCAN_FINISHED_ROGER) { if (img_receiver_) { - data_holder_ptr receiver = img_receiver_(NULL, pack->data); + data_holder_ptr receiver = img_receiver_(IMG_RECEIVER_FINISHED, pack->data); if (receiver) receiver->release(); } diff --git a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h index 118fb2f..ba58747 100644 --- a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h +++ b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h @@ -14,6 +14,9 @@ #include #include +#define IMG_RECEIVER_FINISHED ((LPPACKIMAGE)NULL) +#define IMG_RECEIVER_PAPER_CNT ((LPPACKIMAGE)1) + class async_usb_host; struct libusb_device;