diff --git a/device/gxx-linux/anlogic b/device/gxx-linux/anlogic new file mode 100644 index 0000000..35790d2 Binary files /dev/null and b/device/gxx-linux/anlogic differ diff --git a/device/gxx-linux/applog/applog.cpp b/device/gxx-linux/applog/applog.cpp index 08fa38e..1f625df 100644 --- a/device/gxx-linux/applog/applog.cpp +++ b/device/gxx-linux/applog/applog.cpp @@ -1,8 +1,8 @@ #include "applog.h" -#include -#include -#include -#include +#include "spdlog/spdlog.h" +#include "spdlog/sinks/stdout_color_sinks.h" +#include "spdlog/sinks/basic_file_sink.h" +#include "spdlog/sinks/rotating_file_sink.h" #include "stringex.hpp" #include #include diff --git a/device/gxx-linux/capimage/CImageMerge.cpp b/device/gxx-linux/capimage/CImageMerge.cpp index a7d5f53..667baf0 100644 --- a/device/gxx-linux/capimage/CImageMerge.cpp +++ b/device/gxx-linux/capimage/CImageMerge.cpp @@ -8,68 +8,195 @@ CImageMerge::~CImageMerge() } cv::Mat CImageMerge::MergeImage(cv::Mat &srcMat, int dstwidth, int dstheight) { - cv::Mat retMat(dstheight, dstwidth, CV_8UC3); + cv::Mat retMat(dstheight, dstwidth, CV_8UC3); - if (!srcMat.empty()) - { - std::vector ch_mats; - int blockcnt = 12; - int spitWidth = srcMat.cols / blockcnt; + 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; - } + 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) +cv::Mat CImageMerge::MergeImage(bool iscolor, cv::Mat &srcMat, int dstwidth, int dstheight, unsigned int fgpaversion) { - 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); - } + if (fgpaversion == 0x00090002) + { + int blockcnt = iscolor ? 18 : 6; + int spitWidth = srcMat.cols / blockcnt / 2; //一面的灰度图像宽度 + int abortwidth = spitWidth == 1296 ? 432 : (spitWidth == 648 ? 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 + std::cout << "image is color " << iscolor << std::endl; + cv::Mat dst(dstheight, dstwidth - 2 * abortwidth, CV_8UC(iscolor ? 3 : 1)); + if (!iscolor) + { + for (int i = 0; i < 2; i++) + { + for (int j = 0; j < 6; j++) + { + int index = i == 0 ? 5 : 11; + int bandindex = (i * 6 + j); + if (bandindex == 0 || bandindex == 11) + { + if (bandindex == 0) + srcMat(cv::Rect(bandindex * spitWidth, 0, spitWidth - abortwidth, srcMat.rows)).copyTo(dst(cv::Rect(spitWidth * (index - j), 0, spitWidth - abortwidth, srcMat.rows))); + else + srcMat(cv::Rect(bandindex * spitWidth + abortwidth, 0, spitWidth - abortwidth, srcMat.rows)).copyTo(dst(cv::Rect(spitWidth * (index - j) - abortwidth, 0, spitWidth - abortwidth, srcMat.rows))); + } + else + { + if (bandindex >= 6) + srcMat(cv::Rect(bandindex * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(dst(cv::Rect(spitWidth * (index - j) - 2 * abortwidth, 0, spitWidth, srcMat.rows))); + else + srcMat(cv::Rect(bandindex * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(dst(cv::Rect(spitWidth * (index - j), 0, spitWidth, srcMat.rows))); + } + } + } + srcMat.release(); + } + else + { + std::vector m_splits = { + cv::Mat(dstheight, dstwidth - 2 * abortwidth, CV_8UC1), + cv::Mat(dstheight, dstwidth - 2 * abortwidth, CV_8UC1), + cv::Mat(dstheight, dstwidth - 2 * abortwidth, CV_8UC1)}; + int item_index[3][4] = { + {11, 2, 35, 26}, // R + {17, 8, 29, 20}, // B + {14, 5, 32, 23} // G + }; + + for (size_t j = 0; j < 3; j++) + { + // Front + srcMat(cv::Rect((item_index[j][0] - 0) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 0, 0, spitWidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][0] - 1) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 1, 0, spitWidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][0] - 2) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 2, 0, spitWidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][1] - 0) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 3, 0, spitWidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][1] - 1) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 4, 0, spitWidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][1] - 2) * spitWidth, 0, spitWidth - abortwidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 5, 0, spitWidth - abortwidth, srcMat.rows))); + // Back + srcMat(cv::Rect((item_index[j][2] - 0) * spitWidth + abortwidth, 0, spitWidth - abortwidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 6 - abortwidth, 0, spitWidth - abortwidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][2] - 1) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 7 - 2 * abortwidth, 0, spitWidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][2] - 2) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 8 - 2 * abortwidth, 0, spitWidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][3] - 0) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 9 - 2 * abortwidth, 0, spitWidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][3] - 1) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 10 - 2 * abortwidth, 0, spitWidth, srcMat.rows))); + srcMat(cv::Rect((item_index[j][3] - 2) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 11 - 2 * abortwidth, 0, spitWidth, srcMat.rows))); + } + cv::merge(m_splits, dst); + m_splits.clear(); + } + srcMat.release(); + // static int index=0; + // cv::imwrite(std::to_string(++index)+".bmp",dst); + return dst; + } + else if(fgpaversion == 0x00090001) + { + 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; + } + else if(fgpaversion == 0x0009000a) + { + auto switchblock = [](std::vector> v,cv::Mat& src,cv::Mat& dst,int block_width,int block_height,int abortwidth){ + int copyindex =0; + for(int i=0;i> v {{3,0},{5,1},{4,2},{1,3},{0,4},{2,5},{10,6},{9,7},{11,8},{6,9},{8,10},{7,11}}; + if(!iscolor) + { + int abortwidth = srcMat.cols /12 == 1296 ? 432 :( srcMat.cols /12== 648 ? 216 :144); + cv::Mat dst(srcMat.rows, srcMat.cols - abortwidth*2, CV_8UC1); + switchblock(v,srcMat,dst,srcMat.cols /12,srcMat.rows,abortwidth); + return dst; + } + else + { + cv::Mat retMat(srcMat.rows, srcMat.cols / 3, CV_8UC3); + int spitWidth = srcMat.cols / 12 ; + for(int i=0;i<4;i++) + { + // 1 2 0 + std::vector ch_mats; + if(i < 2){ + ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 0), 0, spitWidth, srcMat.rows))); + ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 2), 0, spitWidth, srcMat.rows))); + ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 1), 0, spitWidth, srcMat.rows))); + } + else + { + ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 2), 0, spitWidth, srcMat.rows))); + ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 0), 0, spitWidth, srcMat.rows))); + ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 1), 0, spitWidth, srcMat.rows))); + } + cv::merge(ch_mats, retMat(cv::Rect(spitWidth * i, 0, spitWidth, srcMat.rows))); + ch_mats.clear(); + } + int abortwidth = retMat.cols /12 == 1296 ? 432 :(retMat.cols /12 == 648 ? 216 :144); + cv::Mat dst(retMat.rows, retMat.cols - abortwidth*2, CV_8UC3); + switchblock(v,retMat,dst,retMat.cols /12,retMat.rows,abortwidth); + printf(" dst.cols = %d dst.rows = %d dst.channels = %d \n",dst.cols,dst.rows,dst.channels()); + return dst; + } + } + return srcMat; +} diff --git a/device/gxx-linux/capimage/CImageMerge.h b/device/gxx-linux/capimage/CImageMerge.h index e93214e..a4e1374 100644 --- a/device/gxx-linux/capimage/CImageMerge.h +++ b/device/gxx-linux/capimage/CImageMerge.h @@ -10,5 +10,5 @@ public: ~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); + cv::Mat MergeImage(bool iscolor,cv::Mat& srcMat,int dstwidth,int dstheight,unsigned int fgpaversion=0x00090001); }; diff --git a/device/gxx-linux/capimage/Capturer.cpp b/device/gxx-linux/capimage/Capturer.cpp index 0fa1f3a..4494a7d 100644 --- a/device/gxx-linux/capimage/Capturer.cpp +++ b/device/gxx-linux/capimage/Capturer.cpp @@ -12,7 +12,6 @@ #include "applog.h" #include "stringex.hpp" #include -#include #include "filetools.h" #include "CameraParam.h" #include "correct_ultis.h" @@ -29,9 +28,12 @@ cv::Mat mBuffMat; cv::Mat out; Capturer::Capturer() - : reset_pin(new GpioOut(Fpga_Reset)), - initDone_pin(new Gpio(71)), - fpgaLoad(new GpioOut(70)), + : 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 GpioOut(Fpga_Load)), bcorrecting(false) { LOG_INIT(); @@ -47,6 +49,9 @@ Capturer::~Capturer() { } +void Capturer::Fpga_regsAccess_reset(bool enable){ + +} void Capturer::open() { cisconfigs = getcisparams(); @@ -97,7 +102,8 @@ void Capturer::open(HGScanConfig config,FPGAConfigParam fpgaparam) if (exp_ratio > 2.0) exp_ratio = 0.1; cisconfigs = getcisparams(); - int height = 1632; + auto hgsize = papersMap[(PaperSize)config.g200params.paper]; + int height = hgsize.height; fpgaComm->setColorMode(config.g200params.color ? 1 : 0); auto info = jsonconfig().getscannerinfo(); //set_sp(config.g200params.color ? cisconfigs.color.sp : cisconfigs.gray.sp); //0x03fa : 0x0bf0 @@ -300,12 +306,11 @@ 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) @@ -348,6 +353,8 @@ void Capturer::setFGPAParmas(int exposures[2][3], int gains[2][6], int offsets[2 void *Capturer::readFrame(int timeout) { auto ret= video->read_frame(timeout); + unsigned int val; + //fpgaComm->update(); return ret; } diff --git a/device/gxx-linux/capimage/Capturer.h b/device/gxx-linux/capimage/Capturer.h index 3df8c93..ee8fd5f 100644 --- a/device/gxx-linux/capimage/Capturer.h +++ b/device/gxx-linux/capimage/Capturer.h @@ -11,7 +11,7 @@ class Capturer : public ICapturer public: Capturer(); virtual ~Capturer(); - + virtual void Fpga_regsAccess_reset(bool enable); virtual void open(); virtual void open(HGScanConfig config,FPGAConfigParam fpgaparam); virtual void close(); diff --git a/device/gxx-linux/capimage/CorrectParam.cpp b/device/gxx-linux/capimage/CorrectParam.cpp index bc51dc6..513e2dd 100644 --- a/device/gxx-linux/capimage/CorrectParam.cpp +++ b/device/gxx-linux/capimage/CorrectParam.cpp @@ -54,6 +54,7 @@ std::vector CorrectParam::GetCorrectParams() std::ifstream i(JSONPATH); json j; i >> j; + i.close(); std::vector vct_param; for (json::iterator it = j.begin(); it != j.end(); ++it) { @@ -114,6 +115,7 @@ void CorrectParam::SaveCorrectParam(FPGAConfigParam& parms) } ofstream ofs(JSONPATH); ofs << std::setw(4) << j << std::endl; + ofs.close(); } void CorrectParam::initdefaultpapram() @@ -129,11 +131,7 @@ void CorrectParam::initdefaultpapram() //彩色 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; @@ -155,7 +153,7 @@ void CorrectParam::initdefaultpapram() //灰度 300 dpi param.ColorMode = 0;//灰度 - param.MaxBright = 200; + param.MaxBright = 220; param.LutPath = LUT300GRAYPATH; param.TextLutPath = TEXTLUT300GRAYPATH; param.Flat_BwPath = LUT300_GRAY_BLACKPATH; @@ -164,11 +162,7 @@ void CorrectParam::initdefaultpapram() 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; @@ -186,7 +180,7 @@ void CorrectParam::initdefaultpapram() js.push_back(t_j); //灰度 200dpi - param.MaxBright = 200; + param.MaxBright = 220; param.ColorMode = 0;//灰度 param.LutPath = LUT200GRAYPATH; param.TextLutPath = TEXTLUT200GRAYPATH; @@ -196,11 +190,7 @@ void CorrectParam::initdefaultpapram() 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; @@ -220,7 +210,7 @@ void CorrectParam::initdefaultpapram() //灰度 600dpi - param.MaxBright = 200; + param.MaxBright = 220; param.ColorMode = 0;//灰度 param.LutPath = LUT600GRAYPATH; param.TextLutPath = TEXTLUT600GRAYPATH; @@ -231,6 +221,7 @@ void CorrectParam::initdefaultpapram() std::ofstream ofs(JSONPATH); ofs << std::setw(4) << js << std::endl; + ofs.close(); } } } diff --git a/device/gxx-linux/capimage/FpgaComm.cpp b/device/gxx-linux/capimage/FpgaComm.cpp index 0c88f22..626336d 100644 --- a/device/gxx-linux/capimage/FpgaComm.cpp +++ b/device/gxx-linux/capimage/FpgaComm.cpp @@ -17,7 +17,7 @@ FpgaComm::FpgaComm() { - m_regsAccess.reset(new UartRegsAccess(MOTOR_UART, 921600, 0x03, 0x83)); + m_regsAccess.reset(new UartRegsAccess(FPGA_UART, 921600, 0x03, 0x83)); update(0); Reg(AledR).sample = 256; @@ -29,7 +29,7 @@ void FpgaComm::regsAccess_reset(bool enable){ if(enable) { if(!m_regsAccess.get()) - m_regsAccess.reset(new UartRegsAccess(MOTOR_UART, 921600, 0x03, 0x83)); + m_regsAccess.reset(new UartRegsAccess(FPGA_UART, 921600, 0x03, 0x83)); update(0); return; } @@ -38,11 +38,15 @@ void FpgaComm::regsAccess_reset(bool enable){ } bool FpgaComm::read(unsigned int addr, unsigned int& val) { - return m_regsAccess->read(addr, val); + if(m_regsAccess.get()) + return m_regsAccess->read(addr, val); + return false; } bool FpgaComm::write(unsigned int addr, unsigned int val) { - return m_regsAccess->write(addr, val); + if(m_regsAccess.get()) + return m_regsAccess->write(addr, val); + return false; } void FpgaComm::setFrameHeight(int height){ @@ -377,14 +381,10 @@ void FpgaComm::setEnTestBit(bool en) 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); + m_regsAccess->write(13,vsp.value); } \ No newline at end of file diff --git a/device/gxx-linux/capimage/FpgaComm.h b/device/gxx-linux/capimage/FpgaComm.h index 9e5df19..71c7c02 100644 --- a/device/gxx-linux/capimage/FpgaComm.h +++ b/device/gxx-linux/capimage/FpgaComm.h @@ -93,7 +93,16 @@ typedef struct CIS_LED_UV unsigned short int ledBSide; } CisLedUv; - +typedef union CIS_VSP +{ + struct + { + unsigned int ASide_VSP:8; + unsigned int BSide_VSP:8; + unsigned int reserved : 16; + } bits; + int value; +} CISVSP; typedef union Fpga_Params { @@ -122,17 +131,6 @@ 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: @@ -189,10 +187,9 @@ public: 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); - + void setVsp(unsigned int Aside,unsigned int BSide); private: FpgaParams fpgaParams; std::shared_ptr m_regsAccess; diff --git a/device/gxx-linux/capimage/GrayLighting.h b/device/gxx-linux/capimage/GrayLighting.h new file mode 100644 index 0000000..8108274 --- /dev/null +++ b/device/gxx-linux/capimage/GrayLighting.h @@ -0,0 +1,105 @@ +#pragma once +#include +#include +#include + +std::vector caculate_abcd(std::vector> point) +{ + int MaxElement = point.size() - 1; + //计算常数f + double f = point[0].second; + //求解 + int n, m; + + std::vector> a; + + 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] = pow(point[i + 1].first, MaxElement - j); + a[i][MaxElement] = point[i + 1].second - 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 < fabs(a[i][j])) { + imax = fabs(a[i][j]); + max = a[i][j];//得到各行中所在列最大元素 + m = i; + } + } + if (fabs(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; +} + +double caculate_value(const std::vector& abcd, double x) +{ + return abcd[0] * x * x * x + abcd[1] * x * x + abcd[2] * x + abcd[3]; +} + +void brightness(cv::Mat& lut, int alpha = 170) +{ + std::vector> pos; + pos.push_back(std::pair(0, 0)); + pos.push_back(std::pair(64, 64)); + pos.push_back(std::pair(alpha, 255)); + pos.push_back(std::pair(255, 255)); + std::vector abcd = caculate_abcd(pos); + + uchar table[256]; + for (int i = 0; i < 256; i++) + table[i] = static_cast(caculate_value(abcd, i)); + + uchar* ptr = lut.data; + for (int i = 0, length = lut.total() * lut.channels(); i < length; i++) + ptr[i] = table[ptr[i]]; +} \ No newline at end of file diff --git a/device/gxx-linux/capimage/ICapturer.h b/device/gxx-linux/capimage/ICapturer.h index dbb3c5e..955bbc8 100644 --- a/device/gxx-linux/capimage/ICapturer.h +++ b/device/gxx-linux/capimage/ICapturer.h @@ -7,10 +7,12 @@ #include "commondef.h" #include "CorrectParam.h" + class ICapturer { public: virtual ~ICapturer() {} + virtual void Fpga_regsAccess_reset(bool enable) = 0; virtual void open() = 0; virtual void open(HGScanConfig config,FPGAConfigParam fpgaparam) = 0; virtual void close() = 0; diff --git a/device/gxx-linux/capimage/MonoCapturer.cpp b/device/gxx-linux/capimage/MonoCapturer.cpp index d1bd23d..b794ad3 100644 --- a/device/gxx-linux/capimage/MonoCapturer.cpp +++ b/device/gxx-linux/capimage/MonoCapturer.cpp @@ -10,9 +10,6 @@ #include "stringex.hpp" #include "filetools.h" #include "CImageMerge.h" -#include "commondef.h" -#include "hgutils.h" -#include "dailex.hpp" #include "jsonconfig.h" #include "ThreadPool.h" @@ -52,7 +49,8 @@ MonoCapturer::MonoCapturer() : vdd_cis_3voff_pin(new GpioOut(CIS_3v3_Off)), 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) + bcorrecting(false), + m_fpgaversion(0x00090001) { LOG_INIT(); fpga_conf_done->setDirection(Gpio::in); @@ -62,7 +60,7 @@ MonoCapturer::MonoCapturer() : vdd_cis_3voff_pin(new GpioOut(CIS_3v3_Off)), fpgaComm->setDelayTime(0X3e8); // fpgaComm->update(); video.reset(new VIDEO_CLASS()); - // GetFpgaparam(0x01,0); + fpgaComm->read(15,m_fpgaversion); } MonoCapturer::~MonoCapturer() @@ -77,12 +75,16 @@ void MonoCapturer::open() { } +void MonoCapturer::Fpga_regsAccess_reset(bool enable){ + if(fpgaComm.get()) + fpgaComm->regsAccess_reset(enable); + fpgaComm->update(0); +} + 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) @@ -95,6 +97,7 @@ void MonoCapturer::open(HGScanConfig config,FPGAConfigParam fpgaparam) int channels = mode == 0x01 ? 3 : 1; int width = channelwidth * channels; auto phyHeight = paperHeight[(PaperSize)config.g200params.paper]; + printf("\n ########## phyHeight = %d ",phyHeight); int pixheight; // = ((int)((phyHeight / 25.4 * (dpi == 0x02 ? 300 : (dpi == 0x03 ? 600 : 200)) + 2) / 3)) * 3 * 2; if (dunnancis) { @@ -111,39 +114,18 @@ void MonoCapturer::open(HGScanConfig config,FPGAConfigParam fpgaparam) 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) + //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; + int startsample = 205; + uint tmp_vs = 0; + fpgaComm->read(15,tmp_vs); + if(tmp_vs >= 0x90002) + startsample = 205; else - startsample = m_fpgaversion == 0x90002? 205 : 208; -#endif + startsample = 208; - 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, @@ -155,15 +137,14 @@ void MonoCapturer::open(HGScanConfig config,FPGAConfigParam fpgaparam) .sp = fpgaparam.Sp}; // 600DPI 0x1450 300DPI 0xe10 fpgaComm->setRegs(0x01, *((int *)(&fpgamod))); fpgaComm->setSample(startsample); + if(tmp_vs != 0x9000a) + fpgaComm->setVsp(2,2); + else{ + fpgaComm->setVsp(80,120); + } 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); @@ -195,11 +176,6 @@ void MonoCapturer::close() //fpga_reload(); } -void MonoCapturer::Fpga_regsAccess_reset(bool enable){ - if(fpgaComm.get()) - fpgaComm->regsAccess_reset(enable); -} - void MonoCapturer::start() { if (video.get()) @@ -232,32 +208,25 @@ int MonoCapturer::getautosizeheight() 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(); + return val; } void MonoCapturer::set_size(int width, int height) { @@ -343,15 +312,11 @@ void MonoCapturer::reset() 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() @@ -366,14 +331,15 @@ int MonoCapturer::color() void MonoCapturer::init_autocorrect(int colormode) { - std::thread t_correctthread = std::thread(&MonoCapturer::correctcolor, this); + std::thread t_correctthread = std::thread(&MonoCapturer::correctcolor, this,colormode); t_correctthread.detach(); } void MonoCapturer::configFPGAParam(int mode, int dpi) { printf("dpi = %d mode = %d \n", dpi, mode); - //fpgaComm->resetADC(); + + 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}; @@ -390,7 +356,7 @@ void MonoCapturer::configFPGAParam(int mode, int dpi) printf("fpgaparam.ExposureB[%d] = %d \n", i, fpgaparam.ExposureB[i % 3]); } - std::this_thread::sleep_for(std::chrono::milliseconds(3)); + std::this_thread::sleep_for(std::chrono::milliseconds(2)); fpgaComm->setAOffset(i, fpgaparam.OffsetF[i]); // fpgaComm->setAOffset(i,offF[i]); printf("fpgaparam.setAOffset[%d] = %d \n", i, fpgaparam.OffsetF[i]); @@ -413,6 +379,7 @@ 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); + fpgaComm->read(15,m_fpgaversion); int config_dpi = dpi == 1 ? 2 : dpi; int channelwidth = config_dpi == 0x02 ? 1296 : (config_dpi == 0x03 ? 2592 : 864); int channels = mode == 0x01 ? 3 : 1; @@ -421,26 +388,15 @@ void MonoCapturer::openDevice(int dpi, int mode) 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); + int startsample = 205; + uint tmp_vs = 0; + fpgaComm->read(15,tmp_vs); + if(tmp_vs >= 0x90002) + startsample = 205; + else + startsample = 208; ModeFpga fpgamod = { .colorMode = mode, .dpi = config_dpi, @@ -455,12 +411,24 @@ void MonoCapturer::openDevice(int dpi, int mode) 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); + if(tmp_vs != 0x9000a) + fpgaComm->setVsp(2,2); + else + { + // ifstream iF("/home/vspF"); + // ifstream iB("/home/vspB"); + // int vspF,vspB; + // iF >> vspF; + // iB >> vspB; + // if(vspF ==0 || vspB == 0) + // { + // vspF = 75; + // vspB = 85; + // } + // printf("!!!!!!!!!!! vspF=%d vspB = %d \n",vspF,vspB); + // fpgaComm->setVsp(vspF,vspB); + fpgaComm->setVsp(80,120); + } configFPGAParam(mode, dpi); video->open(width, dstheight); // 300dpi 7344/2 600dpi 7344 @@ -478,12 +446,11 @@ void MonoCapturer::openDevice(int dpi, int mode) 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) + "次==============================="; @@ -513,6 +480,7 @@ void MonoCapturer::creatcorrectconfig(int dpi, int mode) i++; } printf("creatcorrectconfig %s \n", (mode == IMAGE_COLOR ? " Color" : " Gray")); + //creatLUTData(dpi, mode); video->close(); } @@ -521,20 +489,12 @@ 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); @@ -548,14 +508,11 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) 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 + // cv::imwrite(std::to_string(savelutindex++) + ".jpg", src); CImageMerge t_marge; - cv::Mat mrgmat = t_marge.MergeImage(mode == 0x01, src, dstwidth, height,0x90001); -#endif + cv::Mat mrgmat = t_marge.MergeImage(mode == 0x01, src, dstwidth, height,m_fpgaversion); mrgmat = mrgmat(cv::Rect(0,20,mrgmat.cols,mrgmat.rows-20)); + // cv::imwrite(std::to_string(savelutindex++) + "mrg.jpg", mrgmat); // return false; FPGAConfigParam param = GetFpgaparam(dpi, mode); @@ -563,11 +520,11 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) { double offValues[12]; std::vector bflags; - for (volatile int n = 0; n < 2; n++) + for (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++) // + for (int s = 0; s < 6; s++) // { int k = n * 6 + s; int offset_wdth; @@ -579,9 +536,7 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) { 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); @@ -589,7 +544,6 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) //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; } @@ -597,7 +551,7 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) // std::string clrmode = (mode == 0x01 ? "彩色" : " 灰度"); // log = "开始" + clrmode + "暗场校正 \n"; - for (volatile int s = 0; s < 2; s++) + for (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)); @@ -696,6 +650,7 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) log = "开始彩色明场校正 \r\n"; if (m_captureCallback) m_captureCallback(mode, log); + double coefficient[3] ={ 1.2,0.6,1.2}; for (int s = 0; s < 2; s++) { int exposures[3]; // = (int *)(s == 0 ? param.ExposureF : param.ExposureB); @@ -704,12 +659,14 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) { int k = (3 * s + x); int diff = LIGHT_DIFF(param.MaxBright, *((double *)values + k)); + //int diff = LIGHT_DIFF(param.MaxBright,((values[s][0]*coefficient[0]+values[s][1]*coefficient[1]+values[s][2]*coefficient[2])/3.0)); log += " 明场:" + std::to_string(k) + ";diff:" + std::to_string(diff) + "\r\n"; if(abs(diff) > 30) radio = 2; else radio = 1; double step = diff * radio; + //double step = diff / coefficient[x]; int preStep = *((int *)expStep + k); if (step * preStep < 0) { @@ -752,6 +709,7 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) if (m_captureCallback) m_captureCallback(mode, log); // log =""; + //imwrite("/home/linaro/"+to_string(dpi)+"color.jpg", mrgmat); imwrite(param.Flat_WhitePath, mrgmat); } } @@ -804,7 +762,8 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) if (exp >(param.Sp -5)) exp = (param.Sp -5); - float coffe[3] = {1, 1, 1}; // 0.2, 1,0.51 + //float coffe[3] = {0.8, 1, 1}; // 0.2, 1,0.51 + float coffe[3] = {1,1,1}; for (int k = 0; k < 3; k++) { *(exposures + k) = (int)(exp * coffe[k]); @@ -836,60 +795,88 @@ bool MonoCapturer::saveLutImg(int dpi, int mode, bool black) return isNeedSave; } -void MonoCapturer::correctcolor() +void MonoCapturer::correctcolor(int correctmode) { - 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((correctmode == 0) || (correctmode == 2)){ + 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 "; + if (m_captureCallback) + m_captureCallback(0x01, loginfo); + } + if((correctmode == 0) || (correctmode == 1)){ + loginfo = "Start Correctcolor 200DPI GRAY \r\n"; + if (m_captureCallback) + m_captureCallback(0x01, loginfo); + creatcorrectconfig(0x01, IMAGE_GRAY); + auto 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 "; + if (m_captureCallback) + m_captureCallback(0x02, loginfo); + } + if((correctmode == 0) || (correctmode == 4)){ + loginfo = "Start Correctcolor 300DPI COLOR \r\n"; + if (m_captureCallback) + m_captureCallback(0x01, loginfo); + creatcorrectconfig(0x02, IMAGE_COLOR); + auto 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 "; + if (m_captureCallback) + m_captureCallback(0x02, loginfo); + } + if((correctmode == 0) || (correctmode == 3)){ + loginfo = "Start Correctcolor 300DPI GRAY \r\n"; + if (m_captureCallback) + m_captureCallback(0x01, loginfo); + creatcorrectconfig(0x02, IMAGE_GRAY); + auto 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 "; + if (m_captureCallback) + m_captureCallback(0x03, loginfo); + } + if((correctmode == 0) || (correctmode == 6)){ + loginfo = "Start Correctcolor 600DPI COLOR \r\n"; + if (m_captureCallback) + m_captureCallback(0x01, loginfo); + creatcorrectconfig(0x03, IMAGE_COLOR); + auto 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 "; + if (m_captureCallback) + m_captureCallback(0x03, loginfo); + } + if((correctmode == 0) || (correctmode == 5)){ + loginfo = "Start Correctcolor 600DPI GRAY \r\n"; + if (m_captureCallback) + m_captureCallback(0x01, loginfo); + creatcorrectconfig(0x03, IMAGE_GRAY); + auto 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); + } + if((correctmode < 0) || (correctmode > 6)){ + loginfo = "不支持的校正模式...\r\n"; 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"; + loginfo = "******Correct Done****** " +std::to_string( std::chrono::duration(std::chrono::steady_clock::now() - _start).count()) +"s"; if (m_captureCallback) m_captureCallback(0x03, loginfo); } diff --git a/device/gxx-linux/capimage/MonoCapturer.h b/device/gxx-linux/capimage/MonoCapturer.h index 136c76d..79c810d 100644 --- a/device/gxx-linux/capimage/MonoCapturer.h +++ b/device/gxx-linux/capimage/MonoCapturer.h @@ -41,12 +41,13 @@ public: 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 correctcolor(int correctmode); void fpga_reset(); void fpga_reload(); @@ -64,4 +65,5 @@ private: std::shared_ptr fpga_conf_done; bool bcorrecting; std::thread m_correctthread; + unsigned int m_fpgaversion; }; diff --git a/device/gxx-linux/capimage/SysInforTool.cpp b/device/gxx-linux/capimage/SysInforTool.cpp index 68219bd..7b15e4d 100644 --- a/device/gxx-linux/capimage/SysInforTool.cpp +++ b/device/gxx-linux/capimage/SysInforTool.cpp @@ -149,8 +149,8 @@ std::string SysInforTool::GetSysInfo() 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; + m_sysinfo.MtType = SMBType::MB_DRV_ANLU; char output[512]; get_system_output("uname -a",output,sizeof(output)); std::string ver(output); @@ -160,6 +160,7 @@ std::string SysInforTool::GetSysInfo() struct2json(j,m_sysinfo); std::ofstream o("/usr/local/huago/sysinfo.json"); o << std::setw(4) << j << std::endl; + o.close(); return j.dump(); } diff --git a/device/gxx-linux/capimage/correct_ultis.cpp b/device/gxx-linux/capimage/correct_ultis.cpp index 1774ccd..f32e45a 100644 --- a/device/gxx-linux/capimage/correct_ultis.cpp +++ b/device/gxx-linux/capimage/correct_ultis.cpp @@ -37,11 +37,7 @@ cv::Mat extractRepresentRow2(const cv::Mat &src) 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); @@ -56,7 +52,7 @@ cv::Mat loadLUT(const std::string& file) else if (step == 14688 ||step== 22032 || step == 44064) channel = 432; //486 #else - channel = CHANNEL; + channel = 408; #endif cv::Mat lut(step / channel, 256, CV_8UC(channel)); memcpy(lut.data, dataFile.data, total); @@ -108,6 +104,7 @@ void correctColor(cv::Mat& src, int dpi, int mode,bool isText) if (access(path.c_str(), F_OK) != -1) { lutGrayMat = loadLUT(path); + //brightness(lutGrayMat); } else { @@ -128,17 +125,12 @@ void correctColor(cv::Mat& src, int dpi, int mode,bool isText) 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) -{ +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); @@ -244,6 +236,7 @@ void fittingLUT(const std::vector& points, uchar min_value, uchar max_val } } +#define CHANNEL 408 cv::Mat calcLUT(const cv::Mat& black, const cv::Mat& white, bool isTextCorrection) { std::vector w; @@ -410,7 +403,7 @@ cv::Mat createLUT(const std::vector& mats, bool isTextCorrect) } if (isTextCorrect) { - std::vector points_x = { 0, 25, 230, 255 }, points_y = { 0, 0, 255, 255 }; + std::vector points_x = { 0, 25, 205, 255 }, points_y = { 0, 0, 230, 255 }; std::vector coefficient = caculate(points_x, points_y); uchar buffer[256]; diff --git a/device/gxx-linux/capimage/correct_ultis.h b/device/gxx-linux/capimage/correct_ultis.h index 27859fd..95588f0 100644 --- a/device/gxx-linux/capimage/correct_ultis.h +++ b/device/gxx-linux/capimage/correct_ultis.h @@ -29,5 +29,3 @@ 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/gvideoisp1.cpp b/device/gxx-linux/capimage/gvideoisp1.cpp index 89ff4d8..e9df0f7 100644 --- a/device/gxx-linux/capimage/gvideoisp1.cpp +++ b/device/gxx-linux/capimage/gvideoisp1.cpp @@ -172,7 +172,6 @@ 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 48dfd06..a2b32d0 100644 --- a/device/gxx-linux/capimage/hgutils.cpp +++ b/device/gxx-linux/capimage/hgutils.cpp @@ -289,36 +289,10 @@ 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) +cv::Mat GetMergeMat(int dstwidth ,int dstheight,int type,cv::Mat& mat,unsigned int fpgaversion) { - return CImageMerge().MergeImage(type==CV_8UC3,mat,dstwidth,dstheight,0x90001); + return CImageMerge().MergeImage(type==CV_8UC3,mat,dstwidth,dstheight,fpgaversion); } void savescannerinfo(ScannerNativeParam params) diff --git a/device/gxx-linux/capimage/hgutils.h b/device/gxx-linux/capimage/hgutils.h index 471c30d..0705df1 100644 --- a/device/gxx-linux/capimage/hgutils.h +++ b/device/gxx-linux/capimage/hgutils.h @@ -19,9 +19,8 @@ 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); +cv::Mat GetMergeMat(int dstwidth ,int dstheight,int type,cv::Mat& mat,unsigned int fpgaversion=0x00090001); void correctColor(cv::Mat src, bool enhance); diff --git a/device/gxx-linux/capimage/jsonconfig.cpp b/device/gxx-linux/capimage/jsonconfig.cpp index 0f67b80..9992206 100644 --- a/device/gxx-linux/capimage/jsonconfig.cpp +++ b/device/gxx-linux/capimage/jsonconfig.cpp @@ -77,6 +77,7 @@ void jsonconfig::savecisconfig(HGCorrectConfigs configs) std::ofstream o(JSON_CORRECTFILE_PATH); o << std::setw(4) << m_json << std::endl; + o.close(); } HGCorrectConfigs jsonconfig::getcorrectconfigs() @@ -111,7 +112,7 @@ HGCorrectConfigs jsonconfig::getcorrectconfigs() i.seekg(pos); json m_json; i >> m_json; - + i.close(); cfs.colorCorrect.sp = cfs.color.sp = SP_COLOR_DEFAULT; cfs.grayCorrect.sp = cfs.gray.sp = SP_GRAY_DEFAULT; std::cout <<"GET GET GET GET GET GET" < lc(mtx); + ScannerNativeParam snp; + if (access(JSON_SCANNER_INFO_DIR, 0) == -1) { auto ret = mkdir(JSON_SCANNER_INFO_DIR, 0777); @@ -243,14 +250,13 @@ ScannerNativeParam jsonconfig::getscannerinfo() printf("make dir failed .path=%s \n", JSON_SCANNER_INFO_DIR); } } - - if (access(JSON_SCANNER_INFO_FILE, F_OK) != 0) + if (access(JSON_SCANNER_INFO_FILE, 0) == -1) { + printf("\nerror !!! file no exist"); snp = getdefaultscannerinfo(); savescannerinfo(snp); return snp; } - std::ifstream i(JSON_SCANNER_INFO_FILE); auto pos = i.tellg(); @@ -260,6 +266,7 @@ ScannerNativeParam jsonconfig::getscannerinfo() //printf("file length =%d ", i.tellg()); if (i.tellg() <= 2) { + printf("\nerror !!! file data error"); snp = getdefaultscannerinfo(); savescannerinfo(snp); return snp; @@ -352,9 +359,9 @@ ScannerNativeParam jsonconfig::getscannerinfo() if(!m_json[S_INFO_SPEEDMODE].is_null()) - m_json[S_INFO_SPEEDMODE].get_to(snp.speedmode); + m_json[S_INFO_SPEEDMODE].get_to(snp.speedmode),printf("\n %s Get speedmode value = %d",JSON_SCANNER_INFO_FILE,snp.speedmode); else - snp.speedmode=0; + snp.speedmode=0,printf("\n %s Get speedmode failed ",JSON_SCANNER_INFO_FILE); if(!m_json[S_INFO_PID].is_null()) m_json[S_INFO_PID].get_to(snp.Pid); @@ -362,12 +369,8 @@ ScannerNativeParam jsonconfig::getscannerinfo() { #ifdef G100 snp.Pid = 0x139; - #elif defined G200 - snp.Pid = 0x239; - #elif defined G300 - snp.Pid = 0x339; #else - snp.Pid = 0x439; + snp.Pid = 0x239; #endif } @@ -375,6 +378,21 @@ ScannerNativeParam jsonconfig::getscannerinfo() m_json[S_INFO_VID].get_to(snp.Vid); else snp.Vid = 0x3072; + + if(!m_json[S_INFO_CHUZHI_MOTOR_SPEED_200].is_null()) + m_json[S_INFO_CHUZHI_MOTOR_SPEED_200].get_to(snp.chu_motor_speed_200); + else + snp.chu_motor_speed_200 = 300; + + if(!m_json[S_INFO_CHUZHI_MOTOR_SPEED_300].is_null()) + m_json[S_INFO_CHUZHI_MOTOR_SPEED_300].get_to(snp.chu_motor_speed_300); + else + snp.chu_motor_speed_300 = 200; + + if(!m_json[S_INFO_CHUZHI_MOTOR_SPEED_600].is_null()) + m_json[S_INFO_CHUZHI_MOTOR_SPEED_600].get_to(snp.chu_motor_speed_600); + else + snp.chu_motor_speed_600 = 100; //printf("vid = %d pid =%d \n",snp.Vid,snp.Pid ); return snp; @@ -396,25 +414,17 @@ ScannerNativeParam jsonconfig::getdefaultscannerinfo() param.color_sp=0x27C; param.speedmode = 100; param.Pid = 0x0239; -#elif defined G100 +#else 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=10800; param.clr_maxbright = param.gray_maxbright = 200; - + param.chu_motor_speed_200 = 300; + param.chu_motor_speed_300 = 200; + param.chu_motor_speed_600 = 100; return param; } diff --git a/device/gxx-linux/capimage/jsonconfig.h b/device/gxx-linux/capimage/jsonconfig.h index 1a43092..410e5d7 100644 --- a/device/gxx-linux/capimage/jsonconfig.h +++ b/device/gxx-linux/capimage/jsonconfig.h @@ -2,7 +2,6 @@ #include "json.hpp" #include "commondef.h" #include - using json = nlohmann::json; class jsonconfig diff --git a/device/gxx-linux/capimage/scannersysinfo.h b/device/gxx-linux/capimage/scannersysinfo.h index 23d8ac1..56703f7 100644 --- a/device/gxx-linux/capimage/scannersysinfo.h +++ b/device/gxx-linux/capimage/scannersysinfo.h @@ -1,6 +1,6 @@ #pragma once #include - +#include "commondef.h" enum class SysType { Sys_Linux_Debian=1, diff --git a/device/gxx-linux/capimage/xmake.lua b/device/gxx-linux/capimage/xmake.lua index 8465f32..09de6fe 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_imgcodecs", "opencv_highgui", "opencv_imgproc", { public = true }) + add_links("opencv_core", "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 4ec2b08..3c3d261 100644 --- a/device/gxx-linux/deviceio/DevUtil.h +++ b/device/gxx-linux/deviceio/DevUtil.h @@ -3,6 +3,7 @@ #include #include +#define G300 template void write_dev(std::string path, T value) @@ -20,7 +21,7 @@ enum PORTS Start = 171, Stop = 49, Power = 5, - Fpga_Load = 8, + Fpga_Load = 70, #ifndef G300 Power_12v_Off = 12, diff --git a/device/gxx-linux/deviceio/Gpio.cpp b/device/gxx-linux/deviceio/Gpio.cpp index 92d046f..4842f6d 100644 --- a/device/gxx-linux/deviceio/Gpio.cpp +++ b/device/gxx-linux/deviceio/Gpio.cpp @@ -4,6 +4,10 @@ #include "Gpio.h" #include "DevUtil.h" #include "stringex.hpp" +#include +#include +#include +#include #define IOPATH "%s/gpio%d/%s" @@ -22,8 +26,16 @@ Gpio::Gpio(int port) 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()); + char fpath[128]{}; + sprintf(fpath,"/sys/class/gpio/gpio%d/value",port); + printf("Gpio::Gpio(int port = %d) \n",port); + gpio_fd = open(fpath,O_RDWR); } +Gpio::~Gpio() +{ + close(gpio_fd); +} int Gpio::getPort() { return port; @@ -31,7 +43,13 @@ int Gpio::getPort() void Gpio::setValue(GpioLevel level) { - write_dev(path_value, level); + //write_dev(path_value, level); + if(port == 153 || port == 150) + printf("\n Gpio %d setvalue %d ",port,level==Low?0:1); + if(level == Low) + write(gpio_fd,"0\n",2); + else + write(gpio_fd,"1\n",2); } Gpio::GpioLevel Gpio::getValue() { @@ -45,6 +63,8 @@ std::string Gpio::getDirection() void Gpio::setDirection(std::string direction) { + if(port == 153 || port == 150) + printf("\n Gpio %d setDirection %s ",port,direction.c_str()); write_dev(path_direction, direction); } diff --git a/device/gxx-linux/deviceio/Gpio.h b/device/gxx-linux/deviceio/Gpio.h index 1ee375a..f08a5d8 100644 --- a/device/gxx-linux/deviceio/Gpio.h +++ b/device/gxx-linux/deviceio/Gpio.h @@ -11,6 +11,7 @@ public: }; Gpio(int port); + ~Gpio(); int getPort(); void setValue(GpioLevel level); GpioLevel getValue(); @@ -41,6 +42,7 @@ private: std::string path_edge = "edge"; std::string path_direction = "direction"; std::string path_active_low = "active_low"; + int gpio_fd; }; class GpioOut : public Gpio diff --git a/device/gxx-linux/deviceio/PinMonitor.cpp b/device/gxx-linux/deviceio/PinMonitor.cpp index 2c7249e..b952276 100644 --- a/device/gxx-linux/deviceio/PinMonitor.cpp +++ b/device/gxx-linux/deviceio/PinMonitor.cpp @@ -15,18 +15,6 @@ PinMonitor::PinMonitor(unsigned int pinNum, std::function call_back) this->call_back = call_back; thread_monitor = std::thread(&PinMonitor::monitor, this); //printf("PinMonitor threadid = %d \n",thread_monitor.get_id()); - 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() diff --git a/device/gxx-linux/deviceio/PinMonitor.h b/device/gxx-linux/deviceio/PinMonitor.h index 5032c71..60fd831 100644 --- a/device/gxx-linux/deviceio/PinMonitor.h +++ b/device/gxx-linux/deviceio/PinMonitor.h @@ -11,7 +11,7 @@ public: private: void monitor(); - //sched_param thparm; + Gpio pin; std::function call_back; std::thread thread_monitor; diff --git a/device/gxx-linux/deviceio/xmake.lua b/device/gxx-linux/deviceio/xmake.lua index babe91f..e234c1c 100644 --- a/device/gxx-linux/deviceio/xmake.lua +++ b/device/gxx-linux/deviceio/xmake.lua @@ -5,5 +5,4 @@ target("deviceio") add_syslinks("pthread") add_files("*.cpp") add_includedirs(".", { public = true}) - add_deps("applog") add_packages("common") diff --git a/device/gxx-linux/display/DisplayCenter.cpp b/device/gxx-linux/display/DisplayCenter.cpp new file mode 100644 index 0000000..cb44696 --- /dev/null +++ b/device/gxx-linux/display/DisplayCenter.cpp @@ -0,0 +1,56 @@ +#include "DisplayCenter.h" +#include "LCDDisplay.h" + +DisplayCenter::DisplayCenter():m_lcd(new LCDDisplay()) + ,brun(false) +{ + m_showthread.reset(new std::thread(&DisplayCenter::runloop,this)); + m_distype = DisType::Dis_Idel; +} + +DisplayCenter::~DisplayCenter() +{ + brun = false; + if(m_showthread.get()&& m_showthread->joinable()) + { + m_showthread->join(); + m_showthread.reset(); + } + + if(!m_msgs.IsShutDown()) + m_msgs.ShutDown(); + + m_lcd.reset(); +} + +void DisplayCenter::PutMsg(DisType distype,int pagenum,ClearScreen clearscreen) +{ + m_msgs.Put({distype,clearscreen,(unsigned int )pagenum,""}); + m_distype = distype; + printf("\n ----- distype = %d ",distype); +} + +void DisplayCenter::ResetMsgQueue() +{ + m_msgs.Clear(); +} + +void DisplayCenter::runloop() +{ + brun = true; + while (brun) + { + if(m_msgs.Size()>0) + { + auto msg= m_msgs.Take(); + m_lcd->DisplayState(msg.distype,msg.pagenum,msg.clearscree); + } + else + std::this_thread::sleep_for(std::chrono::milliseconds(2)); + } +} + +DisType DisplayCenter::getcurdistype() +{ + return m_distype; +} \ No newline at end of file diff --git a/device/gxx-linux/display/DisplayCenter.h b/device/gxx-linux/display/DisplayCenter.h new file mode 100644 index 0000000..efe2294 --- /dev/null +++ b/device/gxx-linux/display/DisplayCenter.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include "BlockingQueue.h" +#include "Displaydef.h" + +class LCDDisplay; + +class DisplayCenter +{ +public: + DisplayCenter(); + ~DisplayCenter(); + void PutMsg(DisType distype,int pagenum,ClearScreen clearscreen); + void ResetMsgQueue(); + DisType getcurdistype(); +private: + struct MsgPair{ + DisType distype; + ClearScreen clearscree; + unsigned int pagenum; + std::string infomsg; + }; + void runloop(); +private: + BlockingQueue m_msgs; + std::shared_ptr m_showthread; + std::shared_ptr m_lcd; + volatile DisType m_distype; + bool brun; +}; \ No newline at end of file diff --git a/device/gxx-linux/display/Displaydef.h b/device/gxx-linux/display/Displaydef.h new file mode 100644 index 0000000..e617cd9 --- /dev/null +++ b/device/gxx-linux/display/Displaydef.h @@ -0,0 +1,114 @@ +#pragma once +#include +#include +#include "HgLCDfont.h" + +enum class DisType{ + Dis_Unkown, + Dis_Init,//启动欢迎界面 + Dis_Welcome, + Dis_Idel,//就绪 + Dis_Scan, + Dis_Err_JamIn, + Dis_Err_DoubleFeed, + Dis_Err_PaperScrew, + Dis_Err_Stable, + Dis_Err_AqrImgTimeout, + Dis_Err_CoverOpen, + Dis_Err_JamOut, + Dis_Err_HandModeJam, + Dis_Err_FeedError, + Dis_Err_NoPaper, + Dis_Err_DogEar, + Dis_Err_Size, + Dis_Set_PollPaperIntensity, + Dis_Set_PollPI_High, + Dis_Set_PollPI_Mid, + Dis_Set_PollPI_Low, + Dis_Count_Page, + Dis_Scan_Page, + Dis_Set_ClearPaperPass, + Dis_Set_Count, + Dis_Set_SleepMode, + Dis_Set_SleepMode_5M, + Dis_Set_SleepMode_10M, + Dis_Set_SleepMode_20M, + Dis_Set_SleepMode_30M, + Dis_Set_SleepMode_1H, + Dis_Set_SleepMode_2H, + Dis_Set_SleepMode_4H, + Dis_Set_SleepMode_NEVER, + Dis_Set_Poweroff, + Dis_Set_Return, + Dis_HandMode, + Dis_Set_Item_Return, + Dis_Set_TrayPosition, + Dis_Set_TrayPosition_Low, + Dis_Set_TrayPosition_Mid, + Dis_Set_TrayPosition_High, + Dis_Device_Lock, +}; + +enum class DisDrawtype +{ + DD_All, + DD_TopLeft, + DD_BotRight +}; + +enum class ClearScreen +{ + All, + TOP, + BOT, +}; + +struct DisInfo{ + unsigned char page; + unsigned char col; + DisDrawtype drawtype; + std::vector str; +}; + +static std::map map_Display={ + {DisType::Dis_Welcome,{1,1,DisDrawtype::DD_All,std::vector(f_logo,f_logo+sizeof(f_logo))}}, + {DisType::Dis_Init,{1,1,DisDrawtype::DD_All,std::vector(f_welcome,f_welcome+sizeof(f_welcome))}}, + {DisType::Dis_Idel,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_ready,f_ready+sizeof(f_ready))}}, + {DisType::Dis_Scan,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_scan,f_scan+sizeof(f_scan))}}, + {DisType::Dis_Set_ClearPaperPass,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_clearpaperpass,f_clearpaperpass+sizeof(f_clearpaperpass))}}, + {DisType::Dis_Set_Count,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_countmode,f_countmode+sizeof(f_countmode))}}, + {DisType::Dis_Err_DoubleFeed,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_doublefeed,f_doublefeed+sizeof(f_doublefeed))}}, + {DisType::Dis_Err_Stable,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_stable,f_stable+sizeof(f_stable))}}, + {DisType::Dis_Err_CoverOpen,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_coveropen,f_coveropen+sizeof(f_coveropen))}}, + {DisType::Dis_Err_JamIn,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_paperjam,f_paperjam+sizeof(f_paperjam))}}, + {DisType::Dis_Err_JamOut,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_paperjam,f_paperjam+sizeof(f_paperjam))}}, + {DisType::Dis_Err_HandModeJam,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_handmodepaperjam,f_handmodepaperjam+sizeof(f_handmodepaperjam))}}, + {DisType::Dis_Err_PaperScrew,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_paperscrew,f_paperscrew+sizeof(f_paperscrew))}}, + {DisType::Dis_Err_FeedError,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_feederror,f_feederror+sizeof(f_feederror))}}, + {DisType::Dis_Err_AqrImgTimeout,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_aqrimgtimeout,f_aqrimgtimeout+sizeof(f_aqrimgtimeout))}}, + {DisType::Dis_Err_DogEar,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_dogear,f_dogear+sizeof(f_dogear))}}, + {DisType::Dis_Err_Size,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_size,f_size+sizeof(f_size))}}, + {DisType::Dis_Set_PollPaperIntensity,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_pollpaperintensity,f_pollpaperintensity+sizeof(f_pollpaperintensity))}}, + {DisType::Dis_Set_PollPI_High,{3,96,DisDrawtype::DD_BotRight,std::vector(f_intensityHigh,f_intensityHigh+sizeof(f_intensityHigh))}}, + {DisType::Dis_Set_PollPI_Mid,{3,96,DisDrawtype::DD_BotRight,std::vector(f_intensityMid,f_intensityMid+sizeof(f_intensityMid))}}, + {DisType::Dis_Set_PollPI_Low,{3,96,DisDrawtype::DD_BotRight,std::vector(f_intensityLow,f_intensityLow+sizeof(f_intensityLow))}}, + + {DisType::Dis_Set_TrayPosition,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_trayposition,f_trayposition+sizeof(f_trayposition))}}, + {DisType::Dis_Set_TrayPosition_High,{3,96,DisDrawtype::DD_BotRight,std::vector(f_intensityHigh,f_intensityHigh+sizeof(f_intensityHigh))}}, + {DisType::Dis_Set_TrayPosition_Mid,{3,96,DisDrawtype::DD_BotRight,std::vector(f_intensityMid,f_intensityMid+sizeof(f_intensityMid))}}, + {DisType::Dis_Set_TrayPosition_Low,{3,96,DisDrawtype::DD_BotRight,std::vector(f_traypositionLow,f_traypositionLow+sizeof(f_traypositionLow))}}, + + {DisType::Dis_Count_Page,{3,112,DisDrawtype::DD_BotRight,std::vector(f_page,f_page+sizeof(f_page))}}, + {DisType::Dis_Scan_Page,{3,112,DisDrawtype::DD_BotRight,std::vector(f_page,f_page+sizeof(f_page))}}, + {DisType::Dis_Err_NoPaper,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_nopaper,f_nopaper+sizeof(f_nopaper))}}, + {DisType::Dis_Set_SleepMode,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_sleepmode,f_sleepmode+sizeof(f_sleepmode))}}, + // {DisType::Dis_Set_SleepMode_30M,{3,64,DisDrawtype::DD_BotRight,std::vector(f_30min,f_30min+sizeof(f_30min))}}, + // {DisType::Dis_Set_SleepMode_1H,{3,80,DisDrawtype::DD_BotRight,std::vector(f_1hour,f_1hour+sizeof(f_1hour))}}, + // {DisType::Dis_Set_SleepMode_2H,{3,80,DisDrawtype::DD_BotRight,std::vector(f_2hour,f_2hour+sizeof(f_2hour))}}, + {DisType::Dis_Set_SleepMode_NEVER,{3,80,DisDrawtype::DD_BotRight,std::vector(f_never,f_never+sizeof(f_never))}}, + {DisType::Dis_Set_Return,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_return,f_return+sizeof(f_return))}}, + {DisType::Dis_Set_Poweroff,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_powerof,f_powerof+sizeof(f_powerof))}}, + {DisType::Dis_HandMode,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_handmode,f_handmode+sizeof(f_handmode))}}, + {DisType::Dis_Set_Item_Return,{3,96,DisDrawtype::DD_BotRight,std::vector(f_return,f_return+sizeof(f_return))}}, + {DisType::Dis_Device_Lock,{1,1,DisDrawtype::DD_TopLeft,std::vector(f_deviceLock,f_deviceLock+sizeof(f_deviceLock))}}, +}; diff --git a/device/gxx-linux/display/HgLCDfont.h b/device/gxx-linux/display/HgLCDfont.h new file mode 100644 index 0000000..848c5cf --- /dev/null +++ b/device/gxx-linux/display/HgLCDfont.h @@ -0,0 +1,433 @@ +#pragma once + +/*就绪*/ +static unsigned char f_ready[]={ +0x04,0xE4,0x25,0x26,0x24,0xE4,0x04,0x20,0x20,0xFF,0x20,0xE2,0x2C,0x20,0x20,0x00, +0x10,0x4B,0x82,0x7E,0x02,0x0B,0x90,0x60,0x1C,0x03,0x00,0x3F,0x40,0x40,0x70,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x20,0x30,0xAC,0x63,0x10,0x20,0x24,0x24,0xA4,0x7F,0x24,0x34,0x28,0x26,0x20,0x00, +0x22,0x67,0x22,0x12,0x12,0x04,0x02,0xFF,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00 +}; + +/*图标*/ +static unsigned char f_logo[]={ +0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, +0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x03, +0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0xFC,0xFC, +0x3C,0x3F,0x3F,0x3F,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0xC0,0xF0,0xFC,0xFC,0x3C, +0x3F,0x3F,0x3C,0xFC,0xFC,0xF0,0xC0,0x00,0x00,0x00,0x00,0xF0,0xFC,0x3C,0x3F,0x3F, +0x3F,0x3C,0x3C,0x3C,0x00,0x00,0x00,0xC0,0xF0,0xFC,0xFC,0x3F,0x3F,0x3F,0x3F,0x3C, +0x3C,0xFC,0x30,0x00,0x00,0x00,0x00,0x00,0xC3,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFC,0xC0,0x00,0x00,0x00,0x03,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xF0,0xC0,0xC0,0xC0,0xC0,0xF0,0xFF,0xFF,0x00,0x00,0x00,0x00, +0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0xC0,0xFC, +0xFF,0x3F,0x00,0x03,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x0F,0x00, +0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00, +0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xF0,0x00,0x00,0x0F,0xFF,0xFF,0xF0,0xF0,0xC0, +0xC0,0xC0,0x00,0x00,0x00,0x00,0xFC,0xFF,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x03,0x00,0x00,0x3F,0xFF,0xFF,0x00, +0x00,0x00,0x00,0x00,0x00,0xFF,0x03,0x0F,0x3F,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0x07,0x01,0x01,0x01,0x01,0x07,0xFF,0xFF,0x00,0x00,0x00,0x00, +0xFF,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x7F,0x00,0x00,0x80,0xFF,0xFF, +0xF9,0xE0,0xE0,0xE0,0xE0,0xFF,0xFF,0xFF,0xF8,0x00,0x00,0xFF,0xFF,0xFF,0xE0,0x00, +0x00,0x00,0x07,0x07,0x07,0xFF,0xFF,0x00,0x00,0x00,0x01,0xFF,0xFF,0xE0,0x00,0x00, +0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x01,0x01,0x07,0x07, +0x1F,0xFF,0xFF,0xF8,0x00,0x00,0x7F,0xFF,0xF8,0x80,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xE0,0xFE,0xFF,0xFF,0xE0,0xE0,0xE0,0xE0,0xF9,0xFF,0xFE, +0x80,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x01,0x1F,0xF8,0x80,0x80,0xFF,0xFF, +0x7F,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00,0x00, +0x01,0x1F,0x7F,0x7E,0x78,0x78,0x7E,0x7E,0x1F,0x07,0x00,0x00,0x60,0x7F,0x1F,0x07, +0x01,0x01,0x01,0x01,0x01,0x01,0x07,0x7F,0x7F,0x60,0x00,0x01,0x07,0x1F,0x1F,0x7E, +0x7E,0x78,0x78,0x78,0x78,0x7F,0x7F,0x00,0x00,0x00,0x00,0x07,0x1F,0x1F,0x7E,0x7E, +0x78,0x78,0x7E,0x7E,0x7F,0x1F,0x01,0x00,0x00,0x00,0x00,0x78,0x78,0x78,0x78,0x7E, +0x7E,0x7F,0x1F,0x01,0x00,0x00,0x00,0x01,0x1F,0x7F,0x7E,0x7E,0x78,0x78,0x78,0x7E, +0x7E,0x1E,0x18,0x00,0x78,0x7F,0x7F,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x07,0x7F, +0x7F,0x78,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x1F,0x7F,0x7F,0x7F,0x7F +}; + + +/*欢迎使用*/ +static unsigned char f_welcome[] = { +0x04,0x24,0x44,0x84,0x64,0x9C,0x40,0x30,0x0F,0xC8,0x08,0x08,0x28,0x18,0x00,0x00, +0x10,0x08,0x06,0x01,0x82,0x4C,0x20,0x18,0x06,0x01,0x06,0x18,0x20,0x40,0x80,0x00, +0x40,0x40,0x42,0xCC,0x00,0x00,0xFC,0x04,0x02,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00, +0x00,0x40,0x20,0x1F,0x20,0x40,0x4F,0x44,0x42,0x40,0x7F,0x42,0x44,0x43,0x40,0x00, +0x80,0x60,0xF8,0x07,0x04,0xE4,0x24,0x24,0x24,0xFF,0x24,0x24,0x24,0xE4,0x04,0x00, +0x00,0x00,0xFF,0x00,0x80,0x81,0x45,0x29,0x11,0x2F,0x41,0x41,0x81,0x81,0x80,0x00, +0x00,0x00,0xFE,0x22,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0xFE,0x00,0x00,0x00, +0x80,0x60,0x1F,0x02,0x02,0x02,0x02,0x7F,0x02,0x02,0x42,0x82,0x7F,0x00,0x00,0x00, +}; +/*清理纸道*/ +static unsigned char f_clearpaperpass[]={ +0x10,0x60,0x02,0x8C,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00, +0x04,0x04,0x7E,0x01,0x00,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00, +0x04,0x84,0x84,0xFC,0x84,0x84,0x00,0xFE,0x92,0x92,0xFE,0x92,0x92,0xFE,0x00,0x00, +0x20,0x60,0x20,0x1F,0x10,0x10,0x40,0x44,0x44,0x44,0x7F,0x44,0x44,0x44,0x40,0x00, +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00, +0x40,0x40,0x42,0xCC,0x00,0x08,0xE9,0xAA,0xB8,0xA8,0xA8,0xAA,0xE9,0x08,0x00,0x00, +0x00,0x40,0x20,0x1F,0x20,0x40,0x5F,0x4A,0x4A,0x4A,0x4A,0x4A,0x5F,0x40,0x40,0x00 +}; + +/*计数*/ +static unsigned char f_countmode[] = { +0x40,0x40,0x42,0xCC,0x00,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0x40,0x00, +0x00,0x00,0x00,0x7F,0x20,0x10,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x90,0x52,0x34,0x10,0xFF,0x10,0x34,0x52,0x80,0x70,0x8F,0x08,0x08,0xF8,0x08,0x00, +0x82,0x9A,0x56,0x63,0x22,0x52,0x8E,0x00,0x80,0x40,0x33,0x0C,0x33,0x40,0x80,0x00 +}; + +static unsigned char f_dogear[] = { +0x10,0x10,0x10,0xFF,0x10,0x90,0x00,0xFC,0x44,0x44,0x44,0xC2,0x43,0x42,0x40,0x00, +0x04,0x44,0x82,0x7F,0x01,0x80,0x60,0x1F,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x20,0x10,0xE8,0x24,0x27,0x24,0x24,0xE4,0x24,0x34,0x2C,0x20,0xE0,0x00,0x00,0x00, +0x80,0x60,0x1F,0x09,0x09,0x09,0x09,0x7F,0x09,0x09,0x49,0x89,0x7F,0x00,0x00,0x00, +}; + +static unsigned char f_size[] = { +0x00,0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0xC2,0x42,0x42,0x42,0x7E,0x00,0x00,0x00, +0x80,0x40,0x30,0x0F,0x00,0x00,0x00,0x00,0x03,0x0C,0x10,0x20,0x40,0x80,0x80,0x00, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0x10,0x00, +0x00,0x00,0x00,0x01,0x06,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x02,0x02,0x02,0x02,0x82,0x42,0xF2,0x0E,0x42,0x82,0x02,0x02,0x02,0x00,0x00, +0x10,0x08,0x04,0x02,0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0x01,0x02,0x0C,0x00,0x00, +0x10,0x08,0x04,0x87,0x6C,0x14,0x84,0x94,0x88,0x87,0x84,0xEC,0x94,0x84,0x84,0x00, +0x04,0x02,0x01,0xFF,0x00,0x00,0x00,0x02,0x0C,0x40,0x80,0x7F,0x00,0x00,0x00,0x00, +}; + +/*双张*/ +static unsigned char f_doublefeed[] = { +0x04,0x34,0xC4,0x04,0xC4,0x3C,0x00,0x04,0xFC,0x04,0x04,0x04,0xC4,0x3C,0x00,0x00, +0x40,0x30,0x0C,0x03,0x0C,0x30,0x80,0x40,0x20,0x13,0x0C,0x13,0x20,0x40,0x80,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x02,0xE2,0x22,0x22,0x3E,0x80,0x80,0xFF,0x80,0xA0,0x90,0x88,0x86,0x80,0x80,0x00, +0x00,0x43,0x82,0x42,0x3E,0x00,0x00,0xFF,0x40,0x21,0x06,0x08,0x10,0x20,0x40,0x00 +}; + +/*订书针*/ +static unsigned char f_stable[] = { +0x10,0x10,0xD0,0xFF,0x90,0x50,0x20,0x50,0x4C,0x43,0x4C,0x50,0x20,0x40,0x40,0x00, +0x04,0x03,0x00,0xFF,0x00,0x41,0x44,0x58,0x41,0x4E,0x60,0x58,0x47,0x40,0x40,0x00, +0x10,0x60,0x02,0x8C,0x00,0xFE,0x02,0xF2,0x02,0xFE,0x00,0xF8,0x00,0xFF,0x00,0x00, +0x04,0x04,0x7E,0x01,0x80,0x47,0x30,0x0F,0x10,0x27,0x00,0x47,0x80,0x7F,0x00,0x00, +0x42,0x62,0x52,0x4A,0xC6,0x42,0x52,0x62,0xC2,0x00,0xF8,0x00,0x00,0xFF,0x00,0x00, +0x40,0xC4,0x44,0x44,0x7F,0x24,0x24,0x24,0x20,0x00,0x0F,0x40,0x80,0x7F,0x00,0x00, +0x40,0x40,0x42,0xCC,0x00,0x00,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x00, +0x00,0x00,0x00,0x7F,0x20,0x10,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0xF9,0x02,0x04,0x00,0x00,0x00, +0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x21,0x41,0x21,0x1F,0x00,0x00, +0x40,0x20,0x38,0xE7,0x24,0x24,0x44,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0x00, +0x01,0x01,0x01,0x7F,0x21,0x11,0x09,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, +}; + +/*开盖*/ +static unsigned char f_coveropen[] = { +0x40,0x40,0x42,0xCC,0x00,0x40,0xA0,0x9E,0x82,0x82,0x82,0x9E,0xA0,0x20,0x20,0x00, +0x00,0x00,0x00,0x3F,0x90,0x88,0x40,0x43,0x2C,0x10,0x28,0x46,0x41,0x80,0x80,0x00, +0x80,0x90,0x90,0x48,0x4C,0x57,0x24,0x24,0x24,0x54,0x4C,0x44,0x80,0x80,0x80,0x00, +0x00,0x00,0x00,0xFF,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,0x00, +0x80,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x80,0x00, +0x00,0x80,0x40,0x30,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, +0x00,0x04,0x24,0x24,0x25,0x26,0x24,0xFC,0x24,0x26,0x25,0x24,0x24,0x04,0x00,0x00, +0x81,0x81,0xF9,0x89,0x89,0xF9,0x89,0x89,0x89,0xF9,0x89,0x89,0xF9,0x81,0x81,0x00 +}; + +/*手动模式卡纸*/ +static unsigned char f_handmodepaperjam[] = { +0x00,0x00,0x24,0x24,0x24,0x24,0x24,0xFC,0x22,0x22,0x22,0x23,0x22,0x00,0x00,0x00, +0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,/*"手",0*/ +0x40,0x44,0xC4,0x44,0x44,0x44,0x40,0x10,0x10,0xFF,0x10,0x10,0x10,0xF0,0x00,0x00, +0x10,0x3C,0x13,0x10,0x14,0xB8,0x40,0x30,0x0E,0x01,0x40,0x80,0x40,0x3F,0x00,0x00,/*"动",1*/ +0x10,0x10,0xD0,0xFF,0x90,0x14,0xE4,0xAF,0xA4,0xA4,0xA4,0xAF,0xE4,0x04,0x00,0x00, +0x04,0x03,0x00,0xFF,0x00,0x89,0x4B,0x2A,0x1A,0x0E,0x1A,0x2A,0x4B,0x88,0x80,0x00,/*"模",2*/ +0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0xFF,0x10,0x10,0x11,0x16,0x10,0x00, +0x00,0x20,0x60,0x20,0x3F,0x10,0x10,0x10,0x00,0x03,0x0C,0x10,0x20,0x40,0xF8,0x00,/*"式",3*/ +0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x44,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x02,0x04,0x08,0x10,0x00,0x00,0x00,/*"卡",4*/ +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00,/*"纸",5*/ +}; + +/*手动模式*/ +static unsigned char f_handmode[] = { +0x00,0x00,0x24,0x24,0x24,0x24,0x24,0xFC,0x22,0x22,0x22,0x23,0x22,0x00,0x00,0x00, +0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00, +0x40,0x44,0xC4,0x44,0x44,0x44,0x40,0x10,0x10,0xFF,0x10,0x10,0x10,0xF0,0x00,0x00, +0x10,0x3C,0x13,0x10,0x14,0xB8,0x40,0x30,0x0E,0x01,0x40,0x80,0x40,0x3F,0x00,0x00, +0x10,0x10,0xD0,0xFF,0x90,0x14,0xE4,0xAF,0xA4,0xA4,0xA4,0xAF,0xE4,0x04,0x00,0x00, +0x04,0x03,0x00,0xFF,0x00,0x89,0x4B,0x2A,0x1A,0x0E,0x1A,0x2A,0x4B,0x88,0x80,0x00, +0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0xFF,0x10,0x10,0x11,0x16,0x10,0x00, +0x00,0x20,0x60,0x20,0x3F,0x10,0x10,0x10,0x00,0x03,0x0C,0x10,0x20,0x40,0xF8,0x00, +}; + +/*纸张歪斜*/ +static unsigned char f_paperscrew[] = { +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00, +0x02,0xE2,0x22,0x22,0x3E,0x80,0x80,0xFF,0x80,0xA0,0x90,0x88,0x86,0x80,0x80,0x00, +0x00,0x43,0x82,0x42,0x3E,0x00,0x00,0xFF,0x40,0x21,0x06,0x08,0x10,0x20,0x40,0x00, +0x00,0x42,0x42,0x22,0x22,0x12,0x0A,0x7E,0x02,0x12,0x12,0x22,0x22,0x42,0x00,0x00, +0x40,0x41,0x41,0x7D,0x41,0x41,0x41,0x7F,0x49,0x49,0x49,0x49,0x49,0x41,0x40,0x00, +0x20,0x10,0x28,0x24,0xE3,0x24,0x28,0x10,0x00,0x22,0xCC,0x00,0xFF,0x00,0x00,0x00, +0x20,0x11,0x4D,0x81,0x7F,0x01,0x05,0x19,0x00,0x02,0x02,0x02,0xFF,0x01,0x01,0x00 +}; + +/*卡纸*/ +static unsigned char f_paperjam[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x44,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x02,0x04,0x08,0x10,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00 +}; + +/*卡纸001*/ +static unsigned char f_paperjam001[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x44,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x02,0x04,0x08,0x10,0x00,0x00,0x00, +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00, +0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, +0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, +0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00 +}; + +/*卡纸002*/ +static unsigned char f_paperjam002[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x44,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x02,0x04,0x08,0x10,0x00,0x00,0x00, +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00, +0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, +0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, +0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00 +}; + +/*卡纸003*/ +static unsigned char f_paperjam003[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x44,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x02,0x04,0x08,0x10,0x00,0x00,0x00, +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00, +0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, +0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, +0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00 +}; + +/*搓纸失败*/ +static unsigned char f_feederror[] = { +0x10,0x10,0x10,0xFF,0x10,0x90,0x88,0xA9,0xAE,0xF8,0xA8,0xAC,0xAB,0x88,0x80,0x00, +0x04,0x44,0x82,0x7F,0x21,0x10,0x48,0x46,0x45,0x44,0x7C,0x44,0x44,0x44,0x40,0x00, +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00, +0x00,0x40,0x30,0x1E,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, +0x81,0x81,0x41,0x21,0x11,0x0D,0x03,0x01,0x03,0x0D,0x11,0x21,0x41,0x81,0x81,0x00, +0x00,0xFE,0x02,0xFA,0x02,0xFE,0x40,0x20,0xD8,0x17,0x10,0x10,0xF0,0x10,0x10,0x00, +0x80,0x47,0x30,0x0F,0x10,0x67,0x80,0x40,0x21,0x16,0x08,0x16,0x21,0x40,0x80,0x00 +}; + +/*取图超时*/ +static unsigned char f_aqrimgtimeout[] = { +0x02,0x02,0xFE,0x92,0x92,0x92,0xFE,0x02,0x06,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00, +0x08,0x18,0x0F,0x08,0x08,0x04,0xFF,0x04,0x84,0x40,0x27,0x18,0x27,0x40,0x80,0x00, +0x00,0xFE,0x02,0x42,0x22,0x32,0x5E,0x92,0x52,0x32,0x12,0x02,0x02,0xFE,0x00,0x00, +0x00,0xFF,0x42,0x42,0x42,0x51,0x55,0x64,0x69,0x41,0x42,0x42,0x42,0xFF,0x00,0x00, +0x40,0x48,0x48,0x48,0xFF,0x48,0x48,0x42,0xA2,0x9E,0x82,0xA2,0xC2,0xBE,0x00,0x00, +0x80,0x60,0x1F,0x20,0x7F,0x44,0x44,0x40,0x4F,0x48,0x48,0x48,0x48,0x4F,0x40,0x00, +0x00,0xFC,0x84,0x84,0x84,0xFC,0x00,0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x00, +0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x01,0x06,0x40,0x80,0x7F,0x00,0x00,0x00 +}; + +/*分纸强度*/ +static unsigned char f_pollpaperintensity[] = { +0x80,0x40,0x20,0x90,0x88,0x86,0x80,0x80,0x80,0x83,0x8C,0x10,0x20,0x40,0x80,0x00, +0x00,0x80,0x40,0x20,0x18,0x07,0x00,0x40,0x80,0x40,0x3F,0x00,0x00,0x00,0x00,0x00, +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00, +0x02,0xE2,0x22,0x22,0x3E,0x00,0x80,0x9E,0x92,0x92,0xF2,0x92,0x92,0x9E,0x80,0x00, +0x00,0x43,0x82,0x42,0x3E,0x40,0x47,0x44,0x44,0x44,0x7F,0x44,0x44,0x54,0xE7,0x00, +0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00, +0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00, +}; + +/*高*/ +static unsigned char f_intensityHigh[] = { +0x04,0x04,0x04,0x04,0xF4,0x94,0x95,0x96,0x94,0x94,0xF4,0x04,0x04,0x04,0x04,0x00, +0x00,0xFE,0x02,0x02,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x02,0x82,0xFE,0x00,0x00 +}; + +/*中*/ +static unsigned char f_intensityMid[] = { +0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00, +0x00,0x00,0x0F,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x0F,0x00,0x00,0x00 +}; + +/*弱*/ +static unsigned char f_intensityLow[] = { +0x00,0xF2,0x92,0x92,0x92,0x92,0x9E,0x00,0xF2,0x92,0x92,0x92,0x92,0x9E,0x00,0x00, +0x00,0x10,0x11,0x4A,0x88,0x44,0x3F,0x00,0x10,0x11,0x4A,0x88,0x44,0x3F,0x00,0x00 +}; +/*低*/ +static unsigned char f_traypositionLow[] = { +0x00,0x80,0x60,0xF8,0x07,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x01,0x00,0x00,0xFF,0x00,0x00,0xFF,0x40,0x20,0x00,0x41,0x8E,0x30,0x40,0xF8,0x00 +}; +/*张*/ +static unsigned char f_page[] = { +0x02,0xE2,0x22,0x22,0x3E,0x80,0x80,0xFF,0x80,0xA0,0x90,0x88,0x86,0x80,0x80,0x00, +0x00,0x43,0x82,0x42,0x3E,0x00,0x00,0xFF,0x40,0x21,0x06,0x08,0x10,0x20,0x40,0x00 +}; + +/*扫描*/ +static unsigned char f_scan[] = { +0x10,0x10,0x10,0xFF,0x10,0x90,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0xFC,0x00,0x00, +0x04,0x44,0x82,0x7F,0x01,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7F,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x10,0x10,0x10,0xFF,0x10,0x90,0x04,0xC4,0x5F,0x44,0xC4,0x44,0x5F,0xC4,0x04,0x00, +0x04,0x44,0x82,0x7F,0x01,0x00,0x00,0xFF,0x44,0x44,0x7F,0x44,0x44,0xFF,0x00,0x00 +}; + +/*返回*/ +static unsigned char f_back[] = { +0x40,0x40,0x42,0xCE,0xCC,0x00,0xFC,0xFC,0xA4,0xA4,0x26,0x22,0xA3,0xE3,0x62,0x00, +0x00,0x40,0x60,0x3F,0x3F,0x78,0x5F,0x57,0x58,0x4D,0x47,0x47,0x4D,0x58,0x50,0x40, +0x00,0x00,0xFE,0xFE,0x02,0xF2,0xF2,0x12,0x12,0xF2,0xF2,0x02,0xFE,0xFE,0x00,0x00, +0x00,0x00,0x7F,0x7F,0x20,0x27,0x27,0x24,0x24,0x27,0x27,0x20,0x7F,0x7F,0x00,0x00 +}; + +/*确认*/ +static unsigned char f_confirm[] = { +0x04,0x84,0xE4,0x5C,0x44,0xC4,0x20,0x10,0xE8,0x27,0x24,0xE4,0x34,0x2C,0xE0,0x00, +0x02,0x01,0x7F,0x10,0x10,0x3F,0x80,0x60,0x1F,0x09,0x09,0x3F,0x49,0x89,0x7F,0x00, +0x40,0x40,0x42,0xCC,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x3F,0x90,0x48,0x20,0x18,0x07,0x00,0x07,0x18,0x20,0x40,0x80,0x00 +}; + +/*开*/ +static unsigned char f_opened[] = { +0x80,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x80,0x00, +0x00,0x80,0x40,0x30,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00 +}; + +/*关*/ +static unsigned char f_closed[] = { +0x80,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x80,0x00, +0x00,0x80,0x40,0x30,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00 +}; + +/*无纸*/ +static unsigned char f_nopaper[] = { +0x00,0x40,0x42,0x42,0x42,0xC2,0x7E,0x42,0xC2,0x42,0x42,0x42,0x40,0x40,0x00,0x00, +0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x70,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x20,0x30,0xAC,0x63,0x30,0x00,0xFC,0x84,0x84,0x84,0xFE,0x82,0x83,0x82,0x80,0x00, +0x22,0x67,0x22,0x12,0x12,0x00,0xFF,0x40,0x20,0x00,0x01,0x0E,0x30,0x40,0xF8,0x00 +}; + +/*休眠模式*/ +static unsigned char f_sleepmode[] = { +0x00,0x80,0x60,0xF8,0x07,0x10,0x10,0x10,0xD0,0xFF,0xD0,0x10,0x10,0x10,0x10,0x00, +0x01,0x00,0x00,0xFF,0x10,0x08,0x04,0x03,0x00,0xFF,0x00,0x03,0x04,0x08,0x10,0x00, +0x00,0xFC,0x24,0x24,0x24,0xFC,0x00,0xFE,0x22,0x22,0xE2,0x22,0x22,0x3E,0x00,0x00, +0x00,0x3F,0x11,0x11,0x11,0x3F,0x00,0xFF,0x41,0x21,0x07,0x19,0x21,0x41,0xF1,0x00, +0x10,0x10,0xD0,0xFF,0x90,0x14,0xE4,0xAF,0xA4,0xA4,0xA4,0xAF,0xE4,0x04,0x00,0x00, +0x04,0x03,0x00,0xFF,0x00,0x89,0x4B,0x2A,0x1A,0x0E,0x1A,0x2A,0x4B,0x88,0x80,0x00, +0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0xFF,0x10,0x10,0x11,0x16,0x10,0x00, +0x00,0x20,0x60,0x20,0x3F,0x10,0x10,0x10,0x00,0x03,0x0C,0x10,0x20,0x40,0xF8,0x00 +}; + + +/*三十分钟*/ +static unsigned char f_30min[] = { +0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x00,0x00, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x80,0x40,0x20,0x90,0x88,0x86,0x80,0x80,0x80,0x83,0x8C,0x10,0x20,0x40,0x80,0x00, +0x00,0x80,0x40,0x20,0x18,0x07,0x00,0x40,0x80,0x40,0x3F,0x00,0x00,0x00,0x00,0x00, +0x20,0x10,0x2C,0xE7,0x24,0x24,0x00,0xF0,0x10,0x10,0xFF,0x10,0x10,0xF0,0x00,0x00, +0x01,0x01,0x01,0x7F,0x21,0x11,0x00,0x07,0x02,0x02,0xFF,0x02,0x02,0x07,0x00,0x00, +}; + +/*一小时*/ +static unsigned char f_1hour[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x00, +0x08,0x04,0x03,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00, +0x00,0xFC,0x84,0x84,0x84,0xFC,0x00,0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x00, +0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x01,0x06,0x40,0x80,0x7F,0x00,0x00,0x00 +}; + +/*二小时*/ +static unsigned char f_2hour[] = { +0x02,0xE2,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0xE2,0x02,0x00, +0x00,0xFF,0x00,0x08,0x06,0x01,0x16,0x08,0x06,0x01,0x02,0x4C,0x80,0x7F,0x00,0x00, +0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x00, +0x08,0x04,0x03,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00, +0x00,0xFC,0x84,0x84,0x84,0xFC,0x00,0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x00, +0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x01,0x06,0x40,0x80,0x7F,0x00,0x00,0x00 +}; + +/*不休眠*/ +static unsigned char f_never[] = { +0x00,0x02,0x02,0x02,0x02,0x82,0x42,0xF2,0x0E,0x42,0x82,0x02,0x02,0x02,0x00,0x00, +0x10,0x08,0x04,0x02,0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0x01,0x02,0x0C,0x00,0x00, +0x00,0x80,0x60,0xF8,0x07,0x10,0x10,0x10,0xD0,0xFF,0xD0,0x10,0x10,0x10,0x10,0x00, +0x01,0x00,0x00,0xFF,0x10,0x08,0x04,0x03,0x00,0xFF,0x00,0x03,0x04,0x08,0x10,0x00, +0x00,0xFC,0x24,0x24,0x24,0xFC,0x00,0xFE,0x22,0x22,0xE2,0x22,0x22,0x3E,0x00,0x00, +0x00,0x3F,0x11,0x11,0x11,0x3F,0x00,0xFF,0x41,0x21,0x07,0x19,0x21,0x41,0xF1,0x00 +}; + + +/*返回*/ +static unsigned char f_return[] = { +0x40,0x40,0x42,0xCC,0x00,0x00,0xFC,0x24,0xA4,0x24,0x22,0x22,0xA3,0x62,0x00,0x00, +0x00,0x40,0x20,0x1F,0x20,0x58,0x47,0x50,0x48,0x45,0x42,0x45,0x48,0x50,0x40,0x00, +0x00,0x00,0xFE,0x02,0x02,0xF2,0x12,0x12,0x12,0xF2,0x02,0x02,0xFE,0x00,0x00,0x00, +0x00,0x00,0x7F,0x20,0x20,0x27,0x24,0x24,0x24,0x27,0x20,0x20,0x7F,0x00,0x00,0x00 +}; + +/*关机*/ +static unsigned char f_powerof[] = { +0x00,0x00,0x10,0x11,0x16,0x10,0x10,0xF0,0x10,0x10,0x14,0x13,0x10,0x00,0x00,0x00, +0x81,0x81,0x41,0x41,0x21,0x11,0x0D,0x03,0x0D,0x11,0x21,0x41,0x41,0x81,0x81,0x00, +0x10,0x10,0xD0,0xFF,0x90,0x10,0x00,0xFE,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00, +0x04,0x03,0x00,0xFF,0x00,0x83,0x60,0x1F,0x00,0x00,0x00,0x3F,0x40,0x40,0x78,0x00 +}; + +/*托盘位置*/ +static unsigned char f_trayposition[] = { +0x10,0x10,0x10,0xFF,0x10,0x90,0x04,0x04,0x04,0xFC,0x82,0x82,0x83,0x82,0x80,0x00, +0x04,0x44,0x82,0x7F,0x01,0x00,0x01,0x01,0x01,0x3F,0x40,0x40,0x40,0x40,0x78,0x00, +0x20,0x20,0x20,0xFC,0x24,0x26,0xA5,0x2C,0x34,0x24,0x24,0xFC,0x20,0x20,0x20,0x00, +0x40,0x42,0x7D,0x44,0x44,0x7C,0x44,0x45,0x44,0x7D,0x46,0x45,0x7C,0x40,0x40,0x00, +0x00,0x80,0x60,0xF8,0x07,0x10,0x90,0x10,0x11,0x16,0x10,0x10,0xD0,0x10,0x00,0x00, +0x01,0x00,0x00,0xFF,0x40,0x40,0x41,0x5E,0x40,0x40,0x70,0x4E,0x41,0x40,0x40,0x00, +0x00,0x17,0x15,0xD5,0x55,0x57,0x55,0x7D,0x55,0x57,0x55,0xD5,0x15,0x17,0x00,0x00, +0x40,0x40,0x40,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7F,0x40,0x40,0x40,0x00 +}; + + +/*设备已锁定*/ +static unsigned char f_deviceLock[] = { +0x40,0x40,0x42,0xCC,0x00,0x40,0xA0,0x9E,0x82,0x82,0x82,0x9E,0xA0,0x20,0x20,0x00, +0x00,0x00,0x00,0x3F,0x90,0x88,0x40,0x43,0x2C,0x10,0x28,0x46,0x41,0x80,0x80,0x00,/*"设",0*/ +0x80,0x90,0x90,0x48,0x4C,0x57,0x24,0x24,0x24,0x54,0x4C,0x44,0x80,0x80,0x80,0x00, +0x00,0x00,0x00,0xFF,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,0x00,/*"备",1*/ +0x00,0x00,0xE2,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x00,0x00,0x00, +0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x78,0x00,0x00,/*"已",2*/ +0x20,0x10,0x2C,0xE7,0x24,0x24,0x00,0xE2,0x2C,0x20,0xBF,0x20,0x28,0xE6,0x00,0x00, +0x01,0x01,0x01,0x7F,0x21,0x11,0x80,0x4F,0x20,0x10,0x0F,0x10,0x20,0x4F,0x80,0x00,/*"锁",3*/ +0x10,0x0C,0x44,0x44,0x44,0x44,0x45,0xC6,0x44,0x44,0x44,0x44,0x44,0x14,0x0C,0x00, +0x80,0x40,0x20,0x1E,0x20,0x40,0x40,0x7F,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00,/*"定",4*/ +}; diff --git a/device/gxx-linux/display/LCDDisplay.cpp b/device/gxx-linux/display/LCDDisplay.cpp new file mode 100644 index 0000000..7ddfcc9 --- /dev/null +++ b/device/gxx-linux/display/LCDDisplay.cpp @@ -0,0 +1,152 @@ +#include "LCDDisplay.h" +#include "Lcd.h" +#include +#include +#include +#include "stringex.hpp" + +using namespace std; + +LCDDisplay::LCDDisplay() +{ + lcd.reset(new Lcd()); + lcd->Lcd_Initial_Lcd(false); + // lcd->Lcd_Clear_screen(); + // lcd->Lcd_Display_Graphic_16x16(map_Display[DisType::Dis_Init].page, map_Display[DisType::Dis_Init].col, map_Display[DisType::Dis_Init].str.data(),map_Display[DisType::Dis_Init].str.size()/32); +} + +LCDDisplay::~LCDDisplay() +{ + lcd->Lcd_Clear_screen(); + lcd.reset(); +} + +void LCDDisplay::DisplayState(DisType ds, unsigned int pagenum,ClearScreen clearscree) +{ + if(clearscree == ClearScreen::All) + lcd->Lcd_Clear_screen(); + if(clearscree == ClearScreen::TOP) + lcd->Lcd_Clear_Half_Screen(true); + if(clearscree == ClearScreen::BOT) + lcd->Lcd_Clear_Half_Screen(false); + if (map_Display.count(ds) > 0) + { + m_status = ds; + StopWatch sw; + auto dsinfo = map_Display[ds]; + if (ds == DisType::Dis_Welcome)//show logo + { + lcd->Lcd_Display_Graphic_128x64(dsinfo.page, dsinfo.col, dsinfo.str.data()); + } + else + { + lcd->Lcd_Display_Graphic_16x16(dsinfo.page, dsinfo.col, dsinfo.str.data(), dsinfo.str.size() / 32); + //if (ds == DisType::Dis_Scan || ds == DisType::Dis_Set_Count) //扫描或者计数 更新下半部分内容 + //{ + //lcd->Lcd_Clear_Half_Screen(false); + //lcd->Lcd_Display_String_8x16(3, 96, "0"); + //lcd->Lcd_Display_Graphic_16x16(map_Display[DisType::Dis_Scan_Page].page, map_Display[DisType::Dis_Scan_Page].col, map_Display[DisType::Dis_Scan_Page].str.data(), map_Display[DisType::Dis_Scan_Page].str.size() / 32); + //} + } + + switch (ds) + { + case DisType::Dis_Count_Page: + case DisType::Dis_Scan_Page: + { + //std::string val = std::to_string(pagenum); + //auto offsetdot = bitnum(pagenum) - 1; + std::string val = string_format("%04d",pagenum); + int offsetdot = val.length(); + //printf("\n val = %s lenght = %d",val.c_str(),val.size()); + lcd->Lcd_Display_String_8x16(3, 112 - offsetdot * 8, val.c_str()); //8 -> 一个数字所占点个数宽度 + lcd->Lcd_Display_Graphic_16x16(map_Display[DisType::Dis_Scan_Page].page, map_Display[DisType::Dis_Scan_Page].col, map_Display[DisType::Dis_Scan_Page].str.data(), map_Display[DisType::Dis_Scan_Page].str.size() / 32); + break; + } + case DisType::Dis_Err_JamIn: + { + if(pagenum == 1) + lcd->Lcd_Display_String_8x16(3, 56, "P a 1 0 1"); //8 -> 一个数字所占点个数宽度 + else if(pagenum == 2) + lcd->Lcd_Display_String_8x16(3, 56, "P a 1 0 2"); + else if(pagenum == 3) + lcd->Lcd_Display_String_8x16(3, 56, "P a 1 0 3"); + break; + } + case DisType::Dis_Err_AqrImgTimeout: + lcd->Lcd_Display_String_8x16(3, 56, "G p 0 0 1"); + break; + case DisType::Dis_Err_CoverOpen: + lcd->Lcd_Display_String_8x16(3, 56, "C o 0 0 1"); + break; + case DisType::Dis_Err_PaperScrew: + lcd->Lcd_Display_String_8x16(3, 56, "S K 0 0 1"); + break; + case DisType::Dis_Err_DoubleFeed: + lcd->Lcd_Display_String_8x16(3, 56, "D b 0 0 1"); + break; + case DisType::Dis_Err_NoPaper: + lcd->Lcd_Display_String_8x16(3, 56, "N o 0 0 1"); + break; + case DisType::Dis_Err_Stable: + lcd->Lcd_Display_String_8x16(3, 56, "S T 0 0 1"); + break; + case DisType::Dis_Err_FeedError: + lcd->Lcd_Display_String_8x16(3, 56, "P f 0 0 1"); + break; + case DisType::Dis_Err_DogEar: + lcd->Lcd_Display_String_8x16(3, 56, "Z J 0 0 1"); + break; + case DisType::Dis_Err_Size: + lcd->Lcd_Display_String_8x16(3, 56, "C C 0 0 1"); + break; + default: + break; + } + } + else + { + switch (ds){ + case DisType::Dis_Set_SleepMode_5M: + lcd->Lcd_Display_String_8x16(3, 112, "5M"); + break; + case DisType::Dis_Set_SleepMode_10M: + lcd->Lcd_Display_String_8x16(3, 104, "10M"); + break; + case DisType::Dis_Set_SleepMode_20M: + lcd->Lcd_Display_String_8x16(3, 104, "20M"); + break; + case DisType::Dis_Set_SleepMode_30M: + lcd->Lcd_Display_String_8x16(3, 104, "30M"); + break; + case DisType::Dis_Set_SleepMode_1H: + lcd->Lcd_Display_String_8x16(3, 112, "1H"); + break; + case DisType::Dis_Set_SleepMode_2H: + lcd->Lcd_Display_String_8x16(3, 112, "2H"); + break; + case DisType::Dis_Set_SleepMode_4H: + lcd->Lcd_Display_String_8x16(3, 112, "4H"); + break; + default: + m_status= DisType::Dis_Unkown; + break; + } + } +} + +int LCDDisplay::bitnum(unsigned int num) +{ + int count = 0; + do + { + num = num / 10; + count++; + } while (num > 0); + return count; +} + +DisType LCDDisplay::GetCurrentStatus() const +{ + return m_status; +} \ No newline at end of file diff --git a/device/gxx-linux/display/LCDDisplay.h b/device/gxx-linux/display/LCDDisplay.h new file mode 100644 index 0000000..e5d625b --- /dev/null +++ b/device/gxx-linux/display/LCDDisplay.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include +#include "Displaydef.h" + +class Lcd; + +class LCDDisplay +{ +private: + /* data */ +public: + LCDDisplay(/* args */); + ~LCDDisplay(); + void DisplayState(DisType ds,unsigned int pagenum,ClearScreen clearscree); + DisType GetCurrentStatus() const; +private: + int bitnum(unsigned int num); +private: + std::shared_ptr lcd; + DisType m_status; +}; diff --git a/device/gxx-linux/display/Lcd.cpp b/device/gxx-linux/display/Lcd.cpp new file mode 100644 index 0000000..4e74a9b --- /dev/null +++ b/device/gxx-linux/display/Lcd.cpp @@ -0,0 +1,780 @@ +#include "Lcd.h" +#include +#include +#include +#include "DevUtil.h" + +using namespace std; + +#define IOEXPORTPATH "/sys/class/gpio/export" +#define DELAY_US(t) this_thread::sleep_for(chrono::microseconds((t))) +#define DELAY_MS(t) this_thread::sleep_for(chrono::milliseconds((t))) + +static unsigned char ascii_table_8x16[95][16] = { + + /*-- 文字: --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: ! --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, + + /*-- 文字: " --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: # --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, + + /*-- 文字: $ --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, + + /*-- 文字: % --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, + + /*-- 文字: & --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, + + /*-- 文字: ' --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: ( --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, + + /*-- 文字: ) --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, + + /*-- 文字: * --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, + + /*-- 文字: + --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, + + /*-- 文字: , --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: - --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + + /*-- 文字: . --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: / --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, + + /*-- 文字: 0 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, + + /*-- 文字: 1 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, + + /*-- 文字: 2 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, + + /*-- 文字: 3 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, + + /*-- 文字: 4 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, + + /*-- 文字: 5 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, + + /*-- 文字: 6 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, + + /*-- 文字: 7 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: 8 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, + + /*-- 文字: 9 --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, + + /*-- 文字: : --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, + + /*-- 文字: ; --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: < --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, + + /*-- 文字: = --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, + + /*-- 文字: > --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, + + /*-- 文字: ? --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, + + /*-- 文字: @ --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, + + /*-- 文字: A --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, + + /*-- 文字: B --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, + + /*-- 文字: C --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, + + /*-- 文字: D --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, + + /*-- 文字: E --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, + + /*-- 文字: F --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, + + /*-- 文字: G --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, + + /*-- 文字: H --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, + + /*-- 文字: I --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, + + /*-- 文字: J --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, + + /*-- 文字: K --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, + + /*-- 文字: L --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, + + /*-- 文字: M --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, + + /*-- 文字: N --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, + + /*-- 文字: O --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, + + /*-- 文字: P --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, + + /*-- 文字: Q --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, + + /*-- 文字: R --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, + + /*-- 文字: S --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, + + /*-- 文字: T --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, + + /*-- 文字: U --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, + + /*-- 文字: V --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, + + /*-- 文字: W --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, + + /*-- 文字: X --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, + + /*-- 文字: Y --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, + + /*-- 文字: Z --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, + + /*-- 文字: [ --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, + + /*-- 文字: \ --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, + + /*-- 文字: ] --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, + + /*-- 文字: ^ --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: _ --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + + /*-- 文字: ` --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: a --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, + + /*-- 文字: b --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, + + /*-- 文字: c --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, + + /*-- 文字: d --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, + + /*-- 文字: e --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, + + /*-- 文字: f --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, + + /*-- 文字: g --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, + + /*-- 文字: h --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, + + /*-- 文字: i --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, + + /*-- 文字: j --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, + + /*-- 文字: k --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, + + /*-- 文字: l --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, + + /*-- 文字: m --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, + + /*-- 文字: n --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, + + /*-- 文字: o --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, + + /*-- 文字: p --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, + + /*-- 文字: q --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, + + /*-- 文字: r --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, + + /*-- 文字: s --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, + + /*-- 文字: t --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, + + /*-- 文字: u --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, + + /*-- 文字: v --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, + + /*-- 文字: w --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, + + /*-- 文字: x --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, + + /*-- 文字: y --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, + + /*-- 文字: z --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, + + /*-- 文字: { --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, + + /*-- 文字: | --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + + /*-- 文字: } --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, + + /*-- 文字: ~ --*/ + /*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/ + 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +}; + +static unsigned char ascii_table_5x8[95][5] = { + /*全体ASCII 列表:5x8点阵*/ + 0x00, 0x00, 0x00, 0x00, 0x00, //space + 0x00, 0x00, 0x4f, 0x00, 0x00, //! + 0x00, 0x07, 0x00, 0x07, 0x00, //" + 0x14, 0x7f, 0x14, 0x7f, 0x14, //# + 0x24, 0x2a, 0x7f, 0x2a, 0x12, //$ + 0x23, 0x13, 0x08, 0x64, 0x62, //% + 0x36, 0x49, 0x55, 0x22, 0x50, //& + 0x00, 0x05, 0x07, 0x00, 0x00, //] + 0x00, 0x1c, 0x22, 0x41, 0x00, //( + 0x00, 0x41, 0x22, 0x1c, 0x00, //) + 0x14, 0x08, 0x3e, 0x08, 0x14, //* + 0x08, 0x08, 0x3e, 0x08, 0x08, //+ + 0x00, 0x50, 0x30, 0x00, 0x00, //, + 0x08, 0x08, 0x08, 0x08, 0x08, //- + 0x00, 0x60, 0x60, 0x00, 0x00, //. + 0x20, 0x10, 0x08, 0x04, 0x02, /// + 0x3e, 0x51, 0x49, 0x45, 0x3e, //0 + 0x00, 0x42, 0x7f, 0x40, 0x00, //1 + 0x42, 0x61, 0x51, 0x49, 0x46, //2 + 0x21, 0x41, 0x45, 0x4b, 0x31, //3 + 0x18, 0x14, 0x12, 0x7f, 0x10, //4 + 0x27, 0x45, 0x45, 0x45, 0x39, //5 + 0x3c, 0x4a, 0x49, 0x49, 0x30, //6 + 0x01, 0x71, 0x09, 0x05, 0x03, //7 + 0x36, 0x49, 0x49, 0x49, 0x36, //8 + 0x06, 0x49, 0x49, 0x29, 0x1e, //9 + 0x00, 0x36, 0x36, 0x00, 0x00, //: + 0x00, 0x56, 0x36, 0x00, 0x00, //; + 0x08, 0x14, 0x22, 0x41, 0x00, //< + 0x14, 0x14, 0x14, 0x14, 0x14, //= + 0x00, 0x41, 0x22, 0x14, 0x08, //> + 0x02, 0x01, 0x51, 0x09, 0x06, //? + 0x32, 0x49, 0x79, 0x41, 0x3e, //@ + 0x7e, 0x11, 0x11, 0x11, 0x7e, //A + 0x7f, 0x49, 0x49, 0x49, 0x36, //B + 0x3e, 0x41, 0x41, 0x41, 0x22, //C + 0x7f, 0x41, 0x41, 0x22, 0x1c, //D + 0x7f, 0x49, 0x49, 0x49, 0x41, //E + 0x7f, 0x09, 0x09, 0x09, 0x01, //F + 0x3e, 0x41, 0x49, 0x49, 0x7a, //G + 0x7f, 0x08, 0x08, 0x08, 0x7f, //H + 0x00, 0x41, 0x7f, 0x41, 0x00, //I + 0x20, 0x40, 0x41, 0x3f, 0x01, //J + 0x7f, 0x08, 0x14, 0x22, 0x41, //K + 0x7f, 0x40, 0x40, 0x40, 0x40, //L + 0x7f, 0x02, 0x0c, 0x02, 0x7f, //M + 0x7f, 0x04, 0x08, 0x10, 0x7f, //N + 0x3e, 0x41, 0x41, 0x41, 0x3e, //O + 0x7f, 0x09, 0x09, 0x09, 0x06, //P + 0x3e, 0x41, 0x51, 0x21, 0x5e, //Q + 0x7f, 0x09, 0x19, 0x29, 0x46, //R + 0x46, 0x49, 0x49, 0x49, 0x31, //S + 0x01, 0x01, 0x7f, 0x01, 0x01, //T + 0x3f, 0x40, 0x40, 0x40, 0x3f, //U + 0x1f, 0x20, 0x40, 0x20, 0x1f, //V + 0x3f, 0x40, 0x38, 0x40, 0x3f, //W + 0x63, 0x14, 0x08, 0x14, 0x63, //X + 0x07, 0x08, 0x70, 0x08, 0x07, //Y + 0x61, 0x51, 0x49, 0x45, 0x43, //Z + 0x00, 0x7f, 0x41, 0x41, 0x00, //[ + 0x02, 0x04, 0x08, 0x10, 0x20, //\ +0x00,0x41,0x41,0x7f,0x00,//] + 0x04, 0x02, 0x01, 0x02, 0x04, //^ + 0x40, 0x40, 0x40, 0x40, 0x40, //_ + 0x01, 0x02, 0x04, 0x00, 0x00, //` + 0x20, 0x54, 0x54, 0x54, 0x78, //a + 0x7f, 0x48, 0x48, 0x48, 0x30, //b + 0x38, 0x44, 0x44, 0x44, 0x44, //c + 0x30, 0x48, 0x48, 0x48, 0x7f, //d + 0x38, 0x54, 0x54, 0x54, 0x58, //e + 0x00, 0x08, 0x7e, 0x09, 0x02, //f + 0x48, 0x54, 0x54, 0x54, 0x3c, //g + 0x7f, 0x08, 0x08, 0x08, 0x70, //h + 0x00, 0x00, 0x7a, 0x00, 0x00, //i + 0x20, 0x40, 0x40, 0x3d, 0x00, //j + 0x7f, 0x20, 0x28, 0x44, 0x00, //k + 0x00, 0x41, 0x7f, 0x40, 0x00, //l + 0x7c, 0x04, 0x38, 0x04, 0x7c, //m + 0x7c, 0x08, 0x04, 0x04, 0x78, //n + 0x38, 0x44, 0x44, 0x44, 0x38, //o + 0x7c, 0x14, 0x14, 0x14, 0x08, //p + 0x08, 0x14, 0x14, 0x14, 0x7c, //q + 0x7c, 0x08, 0x04, 0x04, 0x08, //r + 0x48, 0x54, 0x54, 0x54, 0x24, //s + 0x04, 0x04, 0x3f, 0x44, 0x24, //t + 0x3c, 0x40, 0x40, 0x40, 0x3c, //u + 0x1c, 0x20, 0x40, 0x20, 0x1c, //v + 0x3c, 0x40, 0x30, 0x40, 0x3c, //w + 0x44, 0x28, 0x10, 0x28, 0x44, //x + 0x04, 0x48, 0x30, 0x08, 0x04, //y + 0x44, 0x64, 0x54, 0x4c, 0x44, //z + 0x08, 0x36, 0x41, 0x41, 0x00, //{ + 0x00, 0x00, 0x77, 0x00, 0x00, //| + 0x00, 0x41, 0x41, 0x36, 0x08, //} + 0x04, 0x02, 0x02, 0x02, 0x01, //~ +}; + + +Lcd::Lcd() : spi_sck(51), spi_sda(72), spi_cs(154), spi_reset(150), spi_rs(156),COM_BOOT0(153) + +{ + printf("Lcd()\n"); + write_dev(IOEXPORTPATH,51); + write_dev(IOEXPORTPATH,72); + write_dev(IOEXPORTPATH,154); + write_dev(IOEXPORTPATH,150); + write_dev(IOEXPORTPATH,156); + write_dev(IOEXPORTPATH,153); + + COM_BOOT0.setDirection(Gpio::out); + spi_sck.setDirection(Gpio::out); + spi_sda.setDirection(Gpio::out); + spi_cs.setDirection(Gpio::out); + spi_reset.setDirection(Gpio::out); + spi_rs.setDirection(Gpio::out); + + COM_BOOT0.setValue(Gpio::Low); + spi_sck.setValue(Gpio::High); + spi_sda.setValue(Gpio::High); + spi_cs.setValue(Gpio::High); + spi_reset.setValue(Gpio::High); + spi_rs.setValue(Gpio::High); +} + +/*=======写指令========*/ +void Lcd::Lcd_Transfer_Command(int data1) +{ + spi_cs.setValue(Gpio::Low); + spi_rs.setValue(Gpio::Low); + for (int i = 0; i < 8; i++) + { + spi_sck.setValue(Gpio::Low); + + if (data1 & 0x80) + spi_sda.setValue(Gpio::High); + else + spi_sda.setValue(Gpio::Low); + spi_sck.setValue(Gpio::High); + data1 = data1 <<= 1; + } + spi_cs.setValue(Gpio::High); +} + +/*--------写数据------------*/ +void Lcd::Lcd_Transfer_data(int data1) +{ + spi_cs.setValue(Gpio::Low); + spi_rs.setValue(Gpio::High); + for (int i = 0; i < 8; i++) + { + spi_sck.setValue(Gpio::Low); + if (data1 & 0x80) + spi_sda.setValue(Gpio::High); + else + spi_sda.setValue(Gpio::Low); + spi_sck.setValue(Gpio::High); + data1 = data1 <<= 1; + } + spi_cs.setValue(Gpio::High); +} + +/*LCD模块初始化*/ +void Lcd::Lcd_Initial_Lcd(bool biglcd) +{ + spi_cs.setValue(Gpio::Low); + spi_reset.setValue(Gpio::Low); /*低电平复位*/ + DELAY_MS(20); + spi_reset.setValue(Gpio::High); /*复位完毕*/ + DELAY_MS(20); + Lcd_Transfer_Command(0xe2); /*软复位*/ + DELAY_MS(50); + Lcd_Transfer_Command(0x2c); /*升压步聚1*/ + DELAY_MS(50); + Lcd_Transfer_Command(0x2e); /*升压步聚2*/ + DELAY_MS(50); + Lcd_Transfer_Command(0x2f); /*升压步聚3*/ + DELAY_MS(50); + Lcd_Transfer_Command(biglcd?0x21:0x24); /*0X24粗调对比度,可设置范围0x20~0x27*/ + Lcd_Transfer_Command(0x81); /*微调对比度*/ + Lcd_Transfer_Command(biglcd?0x28:0x15); /*45微调对比度的值,可设置范围0x00~0x3f 1f*/ // 0~63 + Lcd_Transfer_Command(0xa2); /*1/9偏压比(bias)0xa2 ,1/7bias 0xa3*/ + Lcd_Transfer_Command(0xc8); /*行扫描顺序:从上到下*/ //原 c0 字体倒置 CF ///////////////////////////////////////////////////////////// + Lcd_Transfer_Command(0xa0); /*列扫描顺序:从左到右*/ //原 a1 字体倒置 A0 //////////////////////////////////////////////// + Lcd_Transfer_Command(0x40); /*起始行:第一行开始*/ + Lcd_Transfer_Command(0xaf); /*开显示*/ + spi_cs.setValue(Gpio::High); +} + +void Lcd::Lcd_Address(unsigned char page, unsigned char column) +{ + spi_cs.setValue(Gpio::Low); + column = column - 1; + page = page - 1; + Lcd_Transfer_Command(0xb0 + page); //设置页地址。每页是8行。一个画面的64行被分成8个页。我们平常所说的第1页,在LCD驱动IC里是第0页,所以在这里减去1*/ + Lcd_Transfer_Command(((column >> 4) & 0x0f) + 0x10); //设置列地址的高4位 + Lcd_Transfer_Command(column & 0x0f); //设置列地址的低4位 +} + +/*全屏清屏*/ +void Lcd::Lcd_Clear_screen() +{ + unsigned char i, j; + spi_cs.setValue(Gpio::Low); + for (i = 0; i < 4; i++) + { + Lcd_Address(1 + i, 1); + for (j = 0; j < 132; j++) + { + Lcd_Transfer_data(0x00); + } + } + spi_cs.setValue(Gpio::High); +} + +//===显示测试画面:例如全显示,隔行显示,隔列显示,雪花显示===== +void Lcd::Lcd_Test_Display(unsigned char data1, unsigned char data2) +{ + int i, j; + for (j = 0; j < 8; j++) + { + spi_cs.setValue(Gpio::Low); + Lcd_Address(j + 1, 1); + for (i = 0; i < 128; i++) + { + Lcd_Transfer_data(data1); + Lcd_Transfer_data(data2); + } + } +} + +/*显示128x64点阵图像*/ +void Lcd::Lcd_Display_Graphic_128x64(unsigned char page, unsigned char column, unsigned char *dp) +{ + int i, j; + for (j = 0; j < 8; j++) + { + spi_cs.setValue(Gpio::Low); + Lcd_Address(page + j, column); + for (i = 0; i < 128; i++) + { + Lcd_Transfer_data(*dp); + dp++; + } + } +} + +/*显示32x32点阵图像、汉字、生僻字或32x32点阵的其他图标*/ +void Lcd::Lcd_Display_graphic_32x32(unsigned char page, unsigned char column, unsigned char *dp) +{ + unsigned char i, j; + spi_cs.setValue(Gpio::Low); + for (j = 0; j < 4; j++) + { + Lcd_Address(page + j, column); + for (i = 0; i < 31; i++) + { + Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + dp++; + } + } +} + +/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/ +void Lcd::Lcd_Display_Graphic_16x16_2(unsigned char reverse, unsigned char page, unsigned char column, unsigned char *dp) +{ + unsigned char i, j; + + spi_cs.setValue(Gpio::Low); + for (j = 0; j < 2; j++) + { + Lcd_Address(page + j, column); + for (i = 0; i < 16; i++) + { + if (reverse == 1) + Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + else + Lcd_Transfer_data(~*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + dp++; + } + } + spi_cs.setValue(Gpio::High); +} + +/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/ +void Lcd::Lcd_Display_Graphic_16x16(unsigned char page, unsigned char column, unsigned char *dp, unsigned int wordcount) +{ + unsigned char i, j, k; + spi_cs.setValue(Gpio::Low); + for (k = 0; k < wordcount; k++) + { + for (j = 0; j < 2; j++) + { + Lcd_Address(page + j, column + 16 * k); + for (i = 0; i < 16; i++) + { + Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + dp++; + } + } + } + spi_cs.setValue(Gpio::High); +} + +/*显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标*/ +void Lcd::Lcd_Display_Graphic_8x16(unsigned char page, unsigned char column, unsigned char *dp) +{ + unsigned char i, j; + spi_cs.setValue(Gpio::Low); + for (j = 0; j < 2; j++) + { + Lcd_Address(page + j, column); + for (i = 0; i < 8; i++) + { + Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + dp++; + } + } + spi_cs.setValue(Gpio::High); +} + +void Lcd::Lcd_Display_String_8x16(unsigned int page, unsigned int column, const char *text) +{ + unsigned int i = 0, j, k, n; + spi_cs.setValue(Gpio::Low); + while (text[i] > 0x00) + { + if ((text[i] >= 0x20) && (text[i] <= 0x7e)) + { + j = text[i] - 0x20; + for (n = 0; n < 2; n++) + { + Lcd_Address(page + n, column); + for (k = 0; k < 8; k++) + { + Lcd_Transfer_data(ascii_table_8x16[j][k + 8 * n]); /*显示5x7的ASCII字到LCD上,y为页地址,x为列地址,最后为数据*/ + } + } + i++; + column += 8; + } + else + i++; + } +} + +void Lcd::Lcd_Display_String_5x8(unsigned int page, unsigned int column, const char *text) +{ + unsigned int i = 0, j, k; + spi_cs.setValue(Gpio::Low); + while (text[i] > 0x00) + { + if ((text[i] >= 0x20) && (text[i] < 0x7e)) + { + j = text[i] - 0x20; + Lcd_Address(page, column); + for (k = 0; k < 5; k++) + { + Lcd_Transfer_data(ascii_table_5x8[j][k]); /*显示5x7的ASCII字到LCD上,y为页地址,x为列地址,最后为数据*/ + } + i++; + column += 6; + } + else + i++; + } +} + +void Lcd::Lcd_Clear_Half_Screen(bool top) +{ + int pageindex = top ? 0 : 2; + int pagemaxindex = top ? 2 : 4; + spi_cs.setValue(Gpio::Low); + for (int i = pageindex; i < pagemaxindex; i++) + { + Lcd_Address(1 + i, 1); + for (int j = 0; j < 132; j++) + { + Lcd_Transfer_data(0x00); + } + } + spi_cs.setValue(Gpio::High); +} diff --git a/device/gxx-linux/display/Lcd.h b/device/gxx-linux/display/Lcd.h new file mode 100644 index 0000000..7028e3b --- /dev/null +++ b/device/gxx-linux/display/Lcd.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include +#include +#include +#include +#include "Gpio.h" + +class Lcd +{ +private: + Gpio spi_sck; + Gpio spi_sda; + Gpio spi_cs; + Gpio spi_reset; + Gpio spi_rs; + Gpio COM_BOOT0; + +public: + Lcd(); + /*=======写指令========*/ + void Lcd_Transfer_Command(int data1); + + /*--------写数据------------*/ + void Lcd_Transfer_data(int data1); + + /*LCD模块初始化*/ + void Lcd_Initial_Lcd(bool biglcd); + + void Lcd_Address(unsigned char page, unsigned char column); + + /*全屏清屏*/ + void Lcd_Clear_screen(); + + void Lcd_Clear_Half_Screen(bool top); + + //===显示测试画面:例如全显示,隔行显示,隔列显示,雪花显示===== + void Lcd_Test_Display(unsigned char data1, unsigned char data2); + + /*显示128x64点阵图像*/ + void Lcd_Display_Graphic_128x64(unsigned char page, unsigned char column, unsigned char *dp); + + /*显示32x32点阵图像、汉字、生僻字或32x32点阵的其他图标*/ + void Lcd_Display_graphic_32x32(unsigned char page, unsigned char column, unsigned char *dp); + + /*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/ + void Lcd_Display_Graphic_16x16_2(unsigned char reverse,unsigned char page,unsigned char column,unsigned char *dp); + + /*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/ + void Lcd_Display_Graphic_16x16(unsigned char page, unsigned char column, unsigned char *dp,unsigned int wordcount); + + /*显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标*/ + void Lcd_Display_Graphic_8x16(unsigned char page, unsigned char column,unsigned char *dp); + + void Lcd_Display_String_8x16(unsigned int page, unsigned int column, const char *text); + + void Lcd_Display_String_5x8(unsigned int page, unsigned int column, const char *text); + +}; + + diff --git a/device/gxx-linux/display/xmake.lua b/device/gxx-linux/display/xmake.lua new file mode 100644 index 0000000..097a0f7 --- /dev/null +++ b/device/gxx-linux/display/xmake.lua @@ -0,0 +1,9 @@ +add_rules("mode.debug", "mode.release") + +target("display") + set_kind("static") + add_syslinks("pthread") + add_files("*.cpp") + add_packages("common") + add_deps("deviceio", {public = true}) + add_includedirs(".", { public = true}) \ No newline at end of file diff --git a/device/gxx-linux/i2c_key/Makefile b/device/gxx-linux/i2c_key/Makefile new file mode 100644 index 0000000..4f9d455 --- /dev/null +++ b/device/gxx-linux/i2c_key/Makefile @@ -0,0 +1,6 @@ +ch455_key:ch455_key.cpp + g++ $^ -o $@ + +clean: + rm ch455_key + \ No newline at end of file diff --git a/device/gxx-linux/i2c_key/ch455_key b/device/gxx-linux/i2c_key/ch455_key new file mode 100644 index 0000000..46666c2 Binary files /dev/null and b/device/gxx-linux/i2c_key/ch455_key differ diff --git a/device/gxx-linux/i2c_key/ch455_key.cpp b/device/gxx-linux/i2c_key/ch455_key.cpp new file mode 100644 index 0000000..bbf1ee7 --- /dev/null +++ b/device/gxx-linux/i2c_key/ch455_key.cpp @@ -0,0 +1,334 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define I2C_SDA 43//GPIO1_B3 +#define I2C_SCL 44//GPIO1_B4 +#define I2C_INT 52 + +typedef unsigned char UINT8; +typedef unsigned short UINT16; + +#define STATUS_SUCCESS 0 +#define STATUS_FAILURE -1 + +#define CH455_GET_KEY 0x0700 // 获取按键,返回按键代码 +#define CH455_SYSOFF 0x0400 // 关闭显示、关闭键盘 + +#define CH455_I2C_ADDR 0x40 // CH455的地址 +#define CH455_I2C_MASK 0x3E // CH455的高字节命令掩码 + +#define CH455_BIT_ENABLE 0x01 +//#define CH455_BIT_ENABLE 0x03 // 开启/关闭位 +#define CH455_BIT_SLEEP 0x04 // 睡眠控制位 + + +#define CH455_SYSON ( CH455_SYSOFF | CH455_BIT_ENABLE ) +#define CH455_SLEEPOFF CH455_SYSOFF // 关闭睡眠 +#define CH455_SLEEPON (CH455_SYSOFF|CH455_BIT_SLEEP) // 开启睡眠 + +static unsigned char TxBuf[24] = {0}; +static unsigned char RxBuf[24] = {0}; + +void CH455_I2c_Stop(void); +void CH455_I2C_WrByte(unsigned char IIC_Byte); + +void delay_us(int i) +{ + int j,k; + for(j=0;j>7)&CH455_I2C_MASK)|CH455_I2C_ADDR); + printf("CH455_Write second byte= %02x\n",(UINT8)cmd); + CH455_I2C_WrByte(((UINT8)(cmd>>7)&CH455_I2C_MASK)|CH455_I2C_ADDR); + CH455_I2C_WrByte((UINT8)cmd); //发送数据 + CH455_I2c_Stop();//结束总线 + printf("CH455_Write end...\n"); + printf("\n"); + return 1; +} + +static unsigned char CH455_Read(void)//读取按键值 +{ + printf("CH455_Read start...\n"); + UINT8 keycode; + CH455_I2c_Start(); //启动总线 + printf("write byte= %02x\n",(UINT8)(CH455_GET_KEY>>7)&CH455_I2C_MASK|0x01|CH455_I2C_ADDR); + CH455_I2C_WrByte((UINT8)(CH455_GET_KEY>>7)&CH455_I2C_MASK|0x01|CH455_I2C_ADDR); + keycode = CH455_I2C_RdByte(); //读取数据 + printf("read byte= %02x\n",keycode); + CH455_I2c_Stop(); //结束总线 + printf("CH455_Read end...\n"); + printf("\n"); + return keycode; +} + +void key_Inter(void) +{ + int ret; + int val = 0; + char buf[8]; + int num; + UINT16 key_value; + pollfd pfd; + pfd.fd = -1; + pfd.fd = open("/sys/class/gpio/gpio52/value", O_RDONLY); + if (pfd.fd > 0) + printf("huagao::open sucess,fd = %d\n",pfd.fd); + else + printf("huagao::open failed,fd = %d\n",pfd.fd); + pfd.events = POLLPRI; + num = read(pfd.fd, buf, 8); // This is to clear the avaible read + for(int i=0;i<8;i++) + printf("huagao::buf[%d] = %d\n",i,buf[i]); + + ret = CH455_Write(CH455_SYSON); + printf("CH455_SYSON = %02x\n",(CH455_SYSON)); + printf("CH455_Read() = %02x\n", CH455_Read()); + key_value = 0xff; + while(1) { + ret = poll(&pfd, 1, 1000); + if (ret > 0) + { + printf("--------------------------------------------\n"); + printf("huagao::poll get date.\n"); + printf("huagao::poll ret = %d\n",ret); + /* + POLLIN: 有普通数据或者优先数据可读 + POLLRDNORM: 有普通数据可读 + POLLRDBAND: 有优先数据可读 + POLLPRI: 有紧急数据可读 + POLLOUT: 有普通数据可写 + POLLWRNORM: 有普通数据可写 + POLLWRBAND: 有紧急数据可写 + POLLERR: 有错误发生 + POLLHUP: 有描述符挂起事件发生 + POLLNVAL: 描述符非法 + */ + if (pfd.revents & POLLPRI) + { + lseek(pfd.fd, 0, SEEK_SET); + num = read(pfd.fd, buf, 8); + buf[num - 1] = '\0'; + ret = atoi(buf); + for(int i=0;i<8;i++) + printf("huagao::buf[%d] = %d\n",i,buf[i]); + printf("huagao::atoi(buf) ret = %d\n",ret); + } + key_value = CH455_Read(); + printf("CH455_Read() = %02x\n", key_value); + printf("--------------------------------------------\n"); + printf("\n"); + } + else if(ret == 0) + { + printf("--------------------------------------------\n"); + printf("huagao::ret = %d\n",ret); + printf("huagao::poll time out.\n"); + printf("--------------------------------------------\n"); + printf("\n"); + } + else + { + printf("--------------------------------------------\n"); + printf("huagao::ret = %d\n",ret); + printf("huagao::poll err.\n"); + printf("--------------------------------------------\n"); + printf("\n"); + } + + } +} +int main(void) +{ + system("echo 52 > /sys/class/gpio/export"); + system("echo in > /sys/class/gpio/gpio52/direction"); + system("echo falling > /sys/class/gpio/gpio52/edge"); + key_Inter(); + return 0; +} + + diff --git a/device/gxx-linux/imgproc/CSizedetect.cpp b/device/gxx-linux/imgproc/CSizedetect.cpp index ed51c89..58c4e53 100644 --- a/device/gxx-linux/imgproc/CSizedetect.cpp +++ b/device/gxx-linux/imgproc/CSizedetect.cpp @@ -1,7 +1,5 @@ #include "CSizedetect.h" #include -#include -#include #include "ImageProcess_Public.h" #include "commondef.h" @@ -134,8 +132,7 @@ int CSizedetect::preprocess(cv::Mat &mat, void *unused) { if(!mat.empty()) { - float width, height; - + float width, height; cv::Mat thre; hg::threshold_Mat(mat, thre, 40); cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(8, 1)); diff --git a/device/gxx-linux/imgproc/CSizedetect.h b/device/gxx-linux/imgproc/CSizedetect.h index a574a81..2b16d10 100644 --- a/device/gxx-linux/imgproc/CSizedetect.h +++ b/device/gxx-linux/imgproc/CSizedetect.h @@ -26,15 +26,16 @@ private: {PaperSize::G400_A5R,HGSize{1653,1165}}, {PaperSize::G400_A6,HGSize{826,1165}}, {PaperSize::G400_A6R,HGSize{1165,826}}, - {PaperSize::G400_B4,HGSize{2023,2866}}, + {PaperSize::G400_B4,HGSize{1969,2780}}, {PaperSize::G400_B5,HGSize{1385,1968}}, {PaperSize::G400_B5R,HGSize{1968,1385}}, {PaperSize::G400_B6R,HGSize{1433,1007}}, {PaperSize::G400_B6,HGSize{1007,1433}}, {PaperSize::G400_DOUBLELETTER,HGSize{2200,3400}}, {PaperSize::G400_LEGAL,HGSize{1700,2800}}, - {PaperSize::G400_LETTER,HGSize{1700,2640}}, + {PaperSize::G400_LETTER,HGSize{1700,2198}}, + {PaperSize::G400_LETTERR,HGSize{2198,1700}}, {PaperSize::G400_LONGLETTER,HGSize{2040,2640}}, - {PaperSize::G400_MAXSIZE,HGSize{2338,6614}} + {PaperSize::G400_MAXSIZE,HGSize{2338,8189}} }; }; \ No newline at end of file diff --git a/device/gxx-linux/imgproc/imageencode.cpp b/device/gxx-linux/imgproc/imageencode.cpp index 68b4c8a..9c4b669 100644 --- a/device/gxx-linux/imgproc/imageencode.cpp +++ b/device/gxx-linux/imgproc/imageencode.cpp @@ -28,31 +28,55 @@ JpegImageEncode::JpegImageEncode(bool bwimg, int dpi) { 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(cv::IMWRITE_RESOLUTION_X); compression_params.push_back(dpi); - compression_params.push_back(/*cv::CV_IMWRITE_JPEG_RESOLUTION_Y*/8); + compression_params.push_back(cv::IMWRITE_RESOLUTION_Y); compression_params.push_back(dpi); } else{ - compression_params.push_back(/*CV_IMWRITE_PNG_STRATEGY*/17); + compression_params.push_back(CV_IMWRITE_PNG_STRATEGY); compression_params.push_back(cv::IMWRITE_PNG_STRATEGY_FIXED); } m_bwimg = bwimg; } +JpegImageEncode::JpegImageEncode(const char* fmt, int dpi) : fmt_(fmt ? fmt : "") +{ + if(fmt_ == "PNG") + { + compression_params.push_back(CV_IMWRITE_PNG_STRATEGY); + compression_params.push_back(cv::IMWRITE_PNG_STRATEGY_FIXED); + } + else + { + compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); + compression_params.push_back(100); + compression_params.push_back(cv::IMWRITE_RESOLUTION_X); + compression_params.push_back(dpi); + compression_params.push_back(cv::IMWRITE_RESOLUTION_Y); + compression_params.push_back(dpi); + } +} JpegImageEncode::~JpegImageEncode() { } MemoryPtr JpegImageEncode::encode(cv::Mat &image) { VectorMemroyPtr mem = VectorMemroyPtr(new VectorMemroy()); - // 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(".jpg", image, mem->buf(), compression_params); + StopWatch sw; + std::string type(m_bwimg ? ".png" : ".jpg"); - //printf("encode time = %0.2f \n", sw.elapsed_ms()); + if(fmt_ == "PNG") + type = ".png"; + else if(fmt_ == "TIFF") + type = ".tiff"; + else + type = ".jpg"; + + cv::imencode(type.c_str(), 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 6b3f3b7..d01f271 100644 --- a/device/gxx-linux/imgproc/imageencode.h +++ b/device/gxx-linux/imgproc/imageencode.h @@ -1,6 +1,7 @@ #pragma once #include "iimageencode.h" #include +#include // typedef struct tagBITMAPFILEHEADER { // WORD bfType; @@ -20,8 +21,11 @@ public: class JpegImageEncode : public IImageEncode { + std::string fmt_; + public: JpegImageEncode(bool bwimg, int dpi); + JpegImageEncode(const char* fmt, int dpi); virtual ~JpegImageEncode(); virtual MemoryPtr encode(cv::Mat& image); diff --git a/device/gxx-linux/imgproc/xmake.lua b/device/gxx-linux/imgproc/xmake.lua index 5609ee6..1062827 100644 --- a/device/gxx-linux/imgproc/xmake.lua +++ b/device/gxx-linux/imgproc/xmake.lua @@ -4,10 +4,11 @@ target("gimgproc") set_kind("static") add_syslinks("pthread") add_files("*.cpp") - add_files("ImageProcess/*.cpp") - del_files("ImageProcess/ImageApplyBarCodeRecognition.cpp") - add_includedirs("ImageProcess", {public = true}) - add_links("opencv_core", "opencv_imgproc", "opencv_imgcodecs", "FreeImage",{ public = true}) + add_files("imageprocess/*.cpp") + --del_files("imageprocess/ImageApplyBarCodeRecognition.cpp") + remove_files("imageprocess/ImageApplyBarCodeRecognition.cpp") + add_includedirs("imageprocess", {public = true}) + add_links("opencv_core", "opencv_imgproc", "opencv_imgcodecs", "freeimageplus", "freeimage",{ public = true}) add_includedirs(".", { public = true}) add_defines("_DIRECT_BUILD") add_packages("common") \ No newline at end of file diff --git a/device/gxx-linux/keymonitor/keymonitor.cpp b/device/gxx-linux/keymonitor/keymonitor.cpp new file mode 100644 index 0000000..14362a5 --- /dev/null +++ b/device/gxx-linux/keymonitor/keymonitor.cpp @@ -0,0 +1,204 @@ +#include "keymonitor.h" +#include "Gpio.h" +#include "PinMonitor.h" +#include + +#define STATUS_SUCCESS 0 +#define STATUS_FAILURE -1 + +#define CH455_GET_KEY 0x0700 // 获取按键,返回按键代码 +#define CH455_SYSOFF 0x0400 // 关闭显示、关闭键盘 + +#define CH455_I2C_ADDR 0x40 // CH455的地址 +#define CH455_I2C_MASK 0x3E // CH455的高字节命令掩码 + +#define CH455_BIT_ENABLE 0x01 +//#define CH455_BIT_ENABLE 0x03 // 开启/关闭位 +#define CH455_BIT_SLEEP 0x04 // 睡眠控制位 + + +#define CH455_SYSON ( CH455_SYSOFF | CH455_BIT_ENABLE ) +#define CH455_SLEEPOFF CH455_SYSOFF // 关闭睡眠 +#define CH455_SLEEPON (CH455_SYSOFF|CH455_BIT_SLEEP) // 开启睡眠 + +KeyMonitor::KeyMonitor(std::function keycall) : m_keycall(keycall) +{ + m_gpioi2c_SCL = std::make_shared(44); //I2C_SCL + m_gpioi2c_SCL->setDirection(Gpio::out); + m_gpioi2c_SDA = std::make_shared(43); //I2C_SDA + m_gpioi2c_SDA->setDirection(Gpio::out); + write_cmd(CH455_SYSON); + printf("read_key = %02x\n", read_key()); + setled(HGLed::Led_All_close); + auto pincall=[&](int pin) + { + auto value= read_key(); + printf("Key = %02x pin value = %d \n",value,pin); + if(m_keycall) + m_keycall(value); + }; + m_keymonitor = std::make_shared(52,pincall); +} + +KeyMonitor::~KeyMonitor() +{ + if(m_gpioi2c_SCL.get()) + m_gpioi2c_SCL.reset(); + + if(m_gpioi2c_SDA.get()) + m_gpioi2c_SDA.reset(); + + if(m_keymonitor.get()) + m_keymonitor.reset(); +} + +void KeyMonitor::init() +{ +} + +void KeyMonitor::i2c_start() +{ + m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SDA->setValue(Gpio::GpioLevel::Low); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low); + std::this_thread::sleep_for(std::chrono::microseconds(5)); +} + +void KeyMonitor::i2c_write(unsigned char cmd) +{ + unsigned char i; + for(i=0; i<8; i++) + { + //IOWR(I2C_SCL, 0); //钳住I2C总线,准备发送数据 + if(cmd & 0x80) + m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High); + else + m_gpioi2c_SDA->setValue(Gpio::GpioLevel::Low); + + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + cmd<<=1; + } + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low); + std::this_thread::sleep_for(std::chrono::microseconds(5)); +} + +unsigned char KeyMonitor::i2c_read() +{ + unsigned char bytedata = 0; + m_gpioi2c_SDA->setDirection(Gpio::in);//将数据设置为输入模式 + //m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + for(int i=0; i<8; i++) + { + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + bytedata <<= 1; + bytedata = bytedata | (m_gpioi2c_SDA->getValue()); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + } + m_gpioi2c_SDA->setDirection(Gpio::out); + m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);////数据线设置回输出模式 + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + return bytedata; +} + +void KeyMonitor::i2c_stop() +{ + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SDA->setValue(Gpio::GpioLevel::Low); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); + m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High); + std::this_thread::sleep_for(std::chrono::microseconds(5)); +} + +void KeyMonitor::write_cmd(unsigned short cmd) +{ + i2c_start(); + i2c_write(((unsigned char)(cmd>>7)&CH455_I2C_MASK)|CH455_I2C_ADDR); + i2c_write(cmd); + i2c_stop(); +} + +unsigned char KeyMonitor::read_key() +{ + unsigned char key=0; + i2c_start(); + i2c_write((unsigned char)(CH455_GET_KEY>>7)&CH455_I2C_MASK|0x01|CH455_I2C_ADDR); + key = i2c_read(); + i2c_stop(); + return key; +} + +std::uint8_t KeyMonitor::getledstate() +{ + return m_ledstate; +} + +void KeyMonitor::setled(HGLed value) +{ + switch (value) + { + case HGLed::Led_All_close: + m_ledstate = 0; + break; +#ifdef G200 + case HGLed::Led_All_open: + m_ledstate = 0xf8; + break; + case HGLed::Led_Count_close: + m_ledstate = m_ledstate & 0xef; + break; + case HGLed::Led_Count_open: + m_ledstate = m_ledstate | 0x10; + break; + case HGLed::Led_DoubleFeed_close: + m_ledstate = m_ledstate & 0xbf; + break; + case HGLed::Led_DoubleFeed_open: + m_ledstate = m_ledstate | 0x40; + break; + case HGLed::Led_Enter_close: + m_ledstate = m_ledstate & 0xf7; + break; + case HGLed::Led_Enter_open: + m_ledstate = m_ledstate | 0x8; + break; + case HGLed::Led_Handle_close: + m_ledstate = m_ledstate & 0xdf; + break; + case HGLed::Led_Handle_open: + m_ledstate = m_ledstate | 0x20; + break; +#endif + default: + break; + } + i2c_start(); + i2c_write(0x6e); + i2c_write(m_ledstate); + i2c_stop(); +} diff --git a/device/gxx-linux/keymonitor/keymonitor.h b/device/gxx-linux/keymonitor/keymonitor.h new file mode 100644 index 0000000..832d8b4 --- /dev/null +++ b/device/gxx-linux/keymonitor/keymonitor.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include +#include "commondef.h" +class PinMonitor; +class Gpio; + +class KeyMonitor +{ +public: +#ifdef G200 + enum class HGKey + { + Key_Enter = 69, + Key_Cancle = 70, + Key_Count = 78, + Key_Handle = 77, + Key_DoubleFeed = 68, + Key_Left = 86, + Key_Menu = 85, + Key_Right = 76, + Key_Clear = 84 + }; +#else + enum class HGKey + { + Key_Enter = 70, + Key_Cancle = 69, + Key_Count = 78, + Key_Menu = 76, + Key_Right = 77, + Key_Clear = 68, + Key_Handle = 3331, + Key_DoubleFeed = 3332, + Key_Left = 3333 + }; +#endif + enum class HGLed + { + Led_Enter_open = 0, + Led_Enter_close, + Led_Count_open, + Led_Count_close, + Led_DoubleFeed_open, + Led_DoubleFeed_close, + Led_Handle_open, + Led_Handle_close, + Led_All_open, + Led_All_close + }; +public: + KeyMonitor(std::function keycall); + void setled(HGLed value); + std::uint8_t getledstate(); + ~KeyMonitor(); +private: + void init(); + void i2c_start(); + void i2c_write(unsigned char cmd); + unsigned char i2c_read(); + void i2c_stop(); + void write_cmd(unsigned short cmd); + unsigned char read_key(); +private: + std::shared_ptr m_keymonitor; + std::shared_ptr m_gpioi2c_SDA; + std::shared_ptr m_gpioi2c_SCL; + std::function m_keycall; + volatile std::uint8_t m_ledstate; +}; \ No newline at end of file diff --git a/device/gxx-linux/keymonitor/xmake.lua b/device/gxx-linux/keymonitor/xmake.lua new file mode 100644 index 0000000..9bd3550 --- /dev/null +++ b/device/gxx-linux/keymonitor/xmake.lua @@ -0,0 +1,9 @@ +add_rules("mode.debug", "mode.release") + +target("keymonitor") + set_kind("static") + add_files("*.cpp") + add_syslinks("pthread") + add_deps("deviceio") + add_packages("common") + add_includedirs(".", { public = true}) \ No newline at end of file diff --git a/device/gxx-linux/mdfusbconfig b/device/gxx-linux/mdfusbconfig deleted file mode 100644 index 59abe80..0000000 Binary files a/device/gxx-linux/mdfusbconfig and /dev/null differ diff --git a/device/gxx-linux/motor_run/CuoZhiMotor.cpp b/device/gxx-linux/motor_run/CuoZhiMotor.cpp deleted file mode 100644 index de9bf86..0000000 --- a/device/gxx-linux/motor_run/CuoZhiMotor.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#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 deleted file mode 100644 index dd89e44..0000000 --- a/device/gxx-linux/motor_run/CuoZhiMotor.h +++ /dev/null @@ -1,92 +0,0 @@ -#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.h b/device/gxx-linux/motor_run/DevUtil.h deleted file mode 100644 index 9018f16..0000000 --- a/device/gxx-linux/motor_run/DevUtil.h +++ /dev/null @@ -1,57 +0,0 @@ -#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/Motor.cpp b/device/gxx-linux/motor_run/Motor.cpp deleted file mode 100644 index 637ea44..0000000 --- a/device/gxx-linux/motor_run/Motor.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#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 deleted file mode 100644 index 101d201..0000000 --- a/device/gxx-linux/motor_run/Motor.h +++ /dev/null @@ -1,72 +0,0 @@ -#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.h b/device/gxx-linux/motor_run/MotorConfig.h deleted file mode 100644 index bf0f96d..0000000 --- a/device/gxx-linux/motor_run/MotorConfig.h +++ /dev/null @@ -1,367 +0,0 @@ -#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 deleted file mode 100644 index 42b9dfc..0000000 --- a/device/gxx-linux/motor_run/MotorControl.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#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 deleted file mode 100644 index 9111b90..0000000 --- a/device/gxx-linux/motor_run/MotorControl.h +++ /dev/null @@ -1,28 +0,0 @@ -#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 deleted file mode 100644 index 2125069..0000000 --- a/device/gxx-linux/motor_run/Pwm.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#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 deleted file mode 100644 index c31bfbf..0000000 --- a/device/gxx-linux/motor_run/Pwm.h +++ /dev/null @@ -1,22 +0,0 @@ -#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 deleted file mode 100644 index c497615..0000000 --- a/device/gxx-linux/motor_run/ZouZhiMotor.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#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 deleted file mode 100644 index 4bb4863..0000000 --- a/device/gxx-linux/motor_run/main.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#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 deleted file mode 100644 index 68a3eeb..0000000 --- a/device/gxx-linux/motor_run/xmake.lua +++ /dev/null @@ -1,89 +0,0 @@ -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/FeedControl.cpp b/device/gxx-linux/motorboard/FeedControl.cpp new file mode 100644 index 0000000..a434180 --- /dev/null +++ b/device/gxx-linux/motorboard/FeedControl.cpp @@ -0,0 +1,69 @@ +#include "FeedControl.h" +#include +#include + +FeedControl::FeedControl(/* args */) : m_thre(0.3) +{ +} + +FeedControl::~FeedControl() +{ +} + +FeedControl::FeedMode FeedControl::GetPredictFeedMode() +{ + return calcFeedMode(); +} + +FeedControl::FeedMode FeedControl::calcFeedMode() +{ + FeedMode mode = FeedMode::FMode_NOChange; + auto infos = m_sessioninfo.GetRecordInfo(); + if (infos.size() < 10) //样本数量大于10了 才做分纸模式分析切换 + return mode; + + unsigned int nDoubleFeedTimes, nJamTimes, nFeedErrorTimes, nTotalScanned; + nDoubleFeedTimes = nJamTimes = nFeedErrorTimes = nTotalScanned = 0; + for (auto &item : infos) + { + if (!item.NormalDone) + { + if (item.DoubleFeed) + nDoubleFeedTimes++; + if (item.Jammed) + nJamTimes++; + if (item.FeedError) + nFeedErrorTimes++; + + nTotalScanned += item.CurrentScaned; + } + } + + double percentHigh = nDoubleFeedTimes / 10.0; + double percentLow = nFeedErrorTimes / 10.0; + printf("\n percentHigh : %f percentLow : %f" , percentHigh,percentLow); + if (percentHigh >= m_thre || percentLow >= m_thre) + { + mode = percentHigh >= percentLow ? FeedMode::FMode_High : FeedMode::FMode_Low; + if(fabs(percentHigh - percentLow) < 0.2) + mode = FeedMode::FMode_Mid; + ResetMode(); + } + printf("\n Calc Feed Mode : %d" , (int)mode); + return mode; +} + +void FeedControl::AppendPattern(MotorSessionInfo::MBTaskRecordInfo info) +{ + m_sessioninfo.UpdateRecordInfo(info); +} + +void FeedControl::SetThre(double thre) +{ + m_thre = thre; +} + +void FeedControl::ResetMode() +{ + m_sessioninfo.RemoveInfos(); +} \ No newline at end of file diff --git a/device/gxx-linux/motorboard/FeedControl.h b/device/gxx-linux/motorboard/FeedControl.h new file mode 100644 index 0000000..771a05b --- /dev/null +++ b/device/gxx-linux/motorboard/FeedControl.h @@ -0,0 +1,31 @@ +#pragma once +#include "MotorSessionInfo.h" + +class FeedControl +{ +public: + enum class FeedMode + { + FMode_Low, + FMode_Mid, + FMode_High, + FMode_NOChange, + }; +public: + FeedControl(/* args */); + ~FeedControl(); + //设置搓纸模式匹配阈值 + void SetThre(double thre); + //获取预测搓纸模式 + FeedMode GetPredictFeedMode(); + //搓纸模式变更时 清除配置记录信息 + void ResetMode(); + //更新走纸流程相关信息 + void AppendPattern(MotorSessionInfo::MBTaskRecordInfo info); +private: + FeedMode calcFeedMode(); +private: + MotorSessionInfo m_sessioninfo; + double m_thre; +}; + diff --git a/device/gxx-linux/motorboard/Imotorboard.cpp b/device/gxx-linux/motorboard/Imotorboard.cpp deleted file mode 100644 index 134f59c..0000000 --- a/device/gxx-linux/motorboard/Imotorboard.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#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 deleted file mode 100644 index bf3b4fe..0000000 --- a/device/gxx-linux/motorboard/Imotorboard.h +++ /dev/null @@ -1,98 +0,0 @@ -#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/Jtag.cpp b/device/gxx-linux/motorboard/Jtag.cpp new file mode 100644 index 0000000..aeab5e2 --- /dev/null +++ b/device/gxx-linux/motorboard/Jtag.cpp @@ -0,0 +1,95 @@ +#include "Jtag.h" + +Jtag::Jtag():jtag_tms(152),jtag_tck(156),jtag_tdi(155),jtag_tdo(72),COM_BOOT0(153) +{ + printf("Jtag()\n"); + char fname[128]; + + write_dev("/sys/class/gpio/export", 152); + write_dev("/sys/class/gpio/export", 156); + write_dev("/sys/class/gpio/export", 155); + write_dev("/sys/class/gpio/export", 72); + write_dev("/sys/class/gpio/export", 153); + + + jtag_tms.setDirection(Gpio::out); + jtag_tck.setDirection(Gpio::out); + jtag_tdi.setDirection(Gpio::out); + jtag_tdo.setDirection(Gpio::in); + COM_BOOT0.setDirection(Gpio::out); + + COM_BOOT0.setValue(Gpio::High); + jtag_tms.setValue(Gpio::Low); + jtag_tck.setValue(Gpio::Low); + jtag_tdi.setValue(Gpio::Low); + + +} + +void Jtag::TMS_Wr(u8 value) +{ + if(value == 1) + jtag_tms.setValue(Gpio::High); + else + jtag_tms.setValue(Gpio::Low); +} + +u8 Jtag::TMS_RD() +{ + return jtag_tms.getValue(); +} + +void Jtag::TCK_Wr(u8 value) +{ + if(value == 1) + jtag_tck.setValue(Gpio::High); + else + jtag_tck.setValue(Gpio::Low); +} + +u8 Jtag::TCK_RD() +{ + return jtag_tck.getValue(); +} + +void Jtag::TDI_Wr(u8 value) +{ + if(value == 1) + jtag_tdi.setValue(Gpio::High); + else + jtag_tdi.setValue(Gpio::Low); +} + +u8 Jtag::TDI_RD() +{ + return jtag_tdi.getValue(); +} + +u8 Jtag::TDO_RD() +{ + return jtag_tdo.getValue(); +} + +void Jtag::Anlogic_Calibration(void) +{ + /*Apply 2 pulses to TCK.*/ + TCK_Wr(1); + TCK_Wr(1); + TCK_Wr(0); + TCK_Wr(1); + TCK_Wr(0); + TCK_Wr(1); + TCK_Wr(1); + /*Delay for 1 millisecond. Pass on 1000 = 1ms delay.*/ + + Anlogic_ProcessRunTestTck(10000) ; + /*Apply 2 pulses to TCK*/ + TCK_Wr(1); + TCK_Wr(1); + TCK_Wr(0); + TCK_Wr(1); + TCK_Wr(0); + TCK_Wr(1); + TCK_Wr(1); + +} \ No newline at end of file diff --git a/device/gxx-linux/motorboard/Jtag.h b/device/gxx-linux/motorboard/Jtag.h new file mode 100644 index 0000000..05edc5d --- /dev/null +++ b/device/gxx-linux/motorboard/Jtag.h @@ -0,0 +1,41 @@ +#ifndef HGSCANSERVICE_JTAG_H +#define HGSCANSERVICE_JTAG_H + +#include +#include +#include +#include +#include +#include "DevUtil.h" +#include "Gpio.h" +#include +#include +#include + +extern void Anlogic_ProcessRunTestTck(int num); + +typedef unsigned int u32; +typedef unsigned char u8; + +class Jtag +{ +private: + Gpio jtag_tms; + Gpio jtag_tck; + Gpio jtag_tdi; + Gpio jtag_tdo; + Gpio COM_BOOT0; + +public: + Jtag(); + void TMS_Wr(u8 value); + u8 TMS_RD(); + void TCK_Wr(u8 value); + u8 TCK_RD(); + void TDI_Wr(u8 value); + u8 TDI_RD(); + u8 TDO_RD(); + void Anlogic_Calibration(void); +}; + +#endif \ No newline at end of file diff --git a/device/gxx-linux/motorboard/Led.cpp b/device/gxx-linux/motorboard/Led.cpp deleted file mode 100644 index 577fc41..0000000 --- a/device/gxx-linux/motorboard/Led.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#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 deleted file mode 100644 index 054ca82..0000000 --- a/device/gxx-linux/motorboard/Led.h +++ /dev/null @@ -1,50 +0,0 @@ -#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/motor_run/MotorConfig.cpp b/device/gxx-linux/motorboard/MotorConfig.cpp similarity index 81% rename from device/gxx-linux/motor_run/MotorConfig.cpp rename to device/gxx-linux/motorboard/MotorConfig.cpp index 102d038..b022ff2 100644 --- a/device/gxx-linux/motor_run/MotorConfig.cpp +++ b/device/gxx-linux/motorboard/MotorConfig.cpp @@ -23,12 +23,14 @@ std::string MotorConfig::GetParams(bool bzouzhi, MTBDType mttype) std::ifstream i(bzouzhi ? MT_TMC216_ZOU_PATH : MT_TMC216_CUO_PATH); i >> j; j_str = j.dump(); + i.close(); } else { std::ifstream i(bzouzhi ? MT_DRV888_ZOU_PATH : MT_DRV888_CUO_PATH); i >> j; j_str = j.dump(); + i.close(); } return j_str; } @@ -63,6 +65,7 @@ void MotorConfig::SetParams(bool bzouzhi, MTBDType mttype, MotorSpeedParamEx &pa ofstream ofs(path); ofs << std::setw(4) << j << std::endl; + ofs.close(); } std::vector MotorConfig::GetMotorSpeedParams(bool bzouzhi, MTBDType mttype) @@ -73,6 +76,7 @@ std::vector MotorConfig::GetMotorSpeedParams(bool bzouzhi, MT std::ifstream i(bzouzhi ? MT_TMC216_ZOU_PATH : MT_TMC216_CUO_PATH); json j; i >> j; + i.close(); for (json::iterator it = j.begin(); it != j.end(); ++it) { auto tmv = it.value(); @@ -86,6 +90,7 @@ std::vector MotorConfig::GetMotorSpeedParams(bool bzouzhi, MT std::ifstream i(bzouzhi ? MT_DRV888_ZOU_PATH : MT_DRV888_CUO_PATH); json j; i >> j; + i.close(); for (json::iterator it = j.begin(); it != j.end(); ++it) { auto tmv = it.value(); @@ -111,22 +116,21 @@ void MotorConfig::initconfigfile() 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; + float ratio = k == 1 ? 1 : (k == 2 ? 1.51 : 2.81); + param.mt_param.finalPeriod = s >= 2 ? 2000 / 4 *ratio: 2000*ratio; // s < 2 drv888 + param.mt_param.finalPeriod = s >= 2 ? 2000 / 4 : 2000; // s < 2 drv888 + param.mt_param.Fmin = s >= 2 ? 80000 / 4 : 80000; + param.mt_param.stepnum = 0.5; + param.mt_param.a = 0.35; + param.mt_param.offset = -5.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]; + param.colormode = t; json t_j; to_json(param, t_j); j.push_back(t_j); @@ -135,16 +139,12 @@ void MotorConfig::initconfigfile() } ofstream ofs(m_jsonpaths[s]); ofs << std::setw(4) << j << std::endl; + ofs.close(); } } } } -void MotorConfig::reset_json(){ - // for(int i =0;i MotorConfig::GetMotorSpeedParams(const std::string& json_str) { std::vector ret; diff --git a/device/gxx-linux/motorboard/MotorConfig.h b/device/gxx-linux/motorboard/MotorConfig.h new file mode 100644 index 0000000..7b87e55 --- /dev/null +++ b/device/gxx-linux/motorboard/MotorConfig.h @@ -0,0 +1,68 @@ +#pragma once +#include +#include "json.hpp" + +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 + +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); +private: + void initconfigfile(); + void to_json(MotorSpeedParamEx& param,json& j); + void from_json(json& j,MotorSpeedParamEx& param); +}; + diff --git a/device/gxx-linux/motorboard/MotorSessionInfo.cpp b/device/gxx-linux/motorboard/MotorSessionInfo.cpp new file mode 100644 index 0000000..20393cb --- /dev/null +++ b/device/gxx-linux/motorboard/MotorSessionInfo.cpp @@ -0,0 +1,117 @@ + +#include "MotorSessionInfo.h" +#include +#include +#include +#include +#include +#define MBTASKPATH "/usr/local/huago/mbtaskinfos.json" + +MotorSessionInfo::MotorSessionInfo(/* args */) : m_maxrecord(10) +{ +} + +MotorSessionInfo::~MotorSessionInfo() +{ +} + +//获取近十次的扫描情况汇总 +std::vector MotorSessionInfo::GetRecordInfo() +{ + + std::vector infos; + json j = getjsonobj(); + printf("\n -------------json = %s",j.dump().c_str()); + for (json::iterator it = j.begin(); it != j.end(); ++it) + { + auto tmv = it.value(); + MBTaskRecordInfo param; + js2struct(param, tmv); + infos.push_back(param); + } + //printf("\n -------------GetRecordInfo size"); + return infos; +} + +//仅记录最近十次的扫描情况,大于十次按照时间戳去除早前的记录 +void MotorSessionInfo::UpdateRecordInfo(MotorSessionInfo::MBTaskRecordInfo info) +{ + auto records = GetRecordInfo(); + //std::sort(records.begin(), records.end()); + printf("\n -------------GetRecordInfo size = %d",records.size()); + if (records.size() > 10) + { + records.pop_back(); + } + records.push_back(info); + savejsonobj(records); +} + +void MotorSessionInfo::RemoveInfos() +{ + std::lock_guard mutex(m_mutex); + system("rm -f /usr/local/huago/mbtaskinfos.json"); +} + +void MotorSessionInfo::js2struct(MotorSessionInfo::MBTaskRecordInfo &info, const json &j) +{ + j["CurrentScaned"].get_to(info.CurrentScaned); + j["DoubleFeed"].get_to(info.DoubleFeed); + j["FeedError"].get_to(info.FeedError); + j["Jammed"].get_to(info.Jammed); + j["NormalDone"].get_to(info.NormalDone); + j["TimeStampStart"].get_to(info.TimeStampStart); + j["TimeStampEnd"].get_to(info.TimeStampEnd); +} + +void MotorSessionInfo::struct2js(const MotorSessionInfo::MBTaskRecordInfo info, json &j) +{ + j["CurrentScaned"] = (info.CurrentScaned); + j["DoubleFeed"] = (info.DoubleFeed); + j["FeedError"] = (info.FeedError); + j["Jammed"] = (info.Jammed); + j["NormalDone"] = (info.NormalDone); + j["TimeStampStart"] = (info.TimeStampStart); + j["TimeStampEnd"] = (info.TimeStampEnd); +} + +json MotorSessionInfo::getjsonobj() +{ + std::lock_guard mutex(m_mutex); + struct stat buff; + json j; + if (stat(MBTASKPATH, &buff) == 0) //存在 + { + std::ifstream i(MBTASKPATH); + // std::string buf; + // buf.resize(buff.st_size); + // i.read(&buf[0],buff.st_size); + // j = json::parse(buf); + i >> j; + i.close(); + //printf("\n ----json = %s ",j.dump().c_str()); + } + return j; +} + + +void MotorSessionInfo::savejsonobj(std::vector infos) +{ + std::lock_guard mutex(m_mutex); + json j= json::array(); + printf("\n -------------infos size = %d",infos.size()); + for (size_t i = 0; i < infos.size(); i++) + { + json jitem; + struct2js(infos[i],jitem); + j.push_back(jitem); + } + + if(!j.empty()) + { + std::ofstream ofs(MBTASKPATH); + ofs << std::setw(4) << j << std::endl; + ofs.close(); + + } +} \ No newline at end of file diff --git a/device/gxx-linux/motorboard/MotorSessionInfo.h b/device/gxx-linux/motorboard/MotorSessionInfo.h new file mode 100644 index 0000000..ed4df00 --- /dev/null +++ b/device/gxx-linux/motorboard/MotorSessionInfo.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include + +using json = nlohmann::json; +class MotorSessionInfo +{ +public: + struct MBTaskRecordInfo + { + unsigned int CurrentScaned; + bool NormalDone; + bool Jammed; + bool DoubleFeed; + bool FeedError; + long TimeStampStart; + long TimeStampEnd; + bool operator < (const MBTaskRecordInfo& info) + { + return this->TimeStampEnd > info.TimeStampEnd; + } + + void Start() + { + std::chrono::time_point tpMicro = \ + std::chrono::time_point_cast(std::chrono::system_clock::now()); + this->TimeStampStart = tpMicro.time_since_epoch().count(); + } + + void Stop() + { + std::chrono::time_point tpMicro = \ + std::chrono::time_point_cast(std::chrono::system_clock::now()); + this->TimeStampEnd = tpMicro.time_since_epoch().count(); + } + }; + //nscanned / 300 nscanned∈[1,300] 即取值范围为[0,1.0] + +public: + MotorSessionInfo(/* args */); + ~MotorSessionInfo(); + std::vector GetRecordInfo();// m_mbtaskrecordInfos; + void UpdateRecordInfo(MBTaskRecordInfo info); + void RemoveInfos(); +private: + void js2struct(MBTaskRecordInfo& info,const json& j); + void struct2js(const MBTaskRecordInfo info,json& j); + json getjsonobj(); + void savejsonobj(std::vector infos); +private: + int m_maxrecord; + std::mutex m_mutex;//避免读写冲突 json文件丢失 +}; diff --git a/device/gxx-linux/motorboard/aje2vec.cpp b/device/gxx-linux/motorboard/aje2vec.cpp new file mode 100644 index 0000000..a8c20ae --- /dev/null +++ b/device/gxx-linux/motorboard/aje2vec.cpp @@ -0,0 +1,918 @@ +/******************************************************************* + * Copyright (c) 2011 -2021 Anlogic Inc. + * The Software is distributed in source code form and is open to + * re-distribution and modification where applicable +*******************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#include +#include +#include + +#include "opcode.h" + +#define AJE_DEBUG + +/* jtag instruction macro list */ +#define INS_REFRESH 0x01 +#define INS_SAMPLE 0x05 +#define INS_READ_STATUS 0x20 +#define INS_BYPASS 0xFF + +#define INS_PROG_SPI 0x39 + +extern unsigned int g_hdr_size; +extern unsigned int g_hir_size; +extern unsigned int g_tdr_size; +extern unsigned int g_tir_size; + +extern unsigned char* g_hdr_data; +extern unsigned char* g_hir_data; +extern unsigned char* g_tdr_data; +extern unsigned char* g_tir_data; + +/* some static & global variables */ +static char s_compress = FULL_MODE; /* compress mode */ +static long int s_cfg_start_pos = 0; /* the start cfg position in aje file */ +static int s_done_status = 1; /* done pin status */ +static int s_find_refresh_ins = 0; /* the flag that refresh instrcution has been found or not */ +static int s_cur_level = 0; /* for daisy chain, current level */ +static int s_total_level = 0; /* for daisy chain, total level */ + +FILE* g_aje_file; +char g_aje_crc[3]; +long int g_freq = 0; +unsigned char s_idcode_pub = IDCODE_PUB; +static unsigned int s_cascade = 0; /* cascade flag */ + +/* function declared in decode.c */ +extern unsigned char* Anlogic_BytesDecode(long bytes); +extern unsigned char* Anlogic_NibbleDecode(long bytes); +extern unsigned char* Anlogic_HuffmanDecode(long bytes); +extern unsigned char* Anlogic_LzwDecode(long bytes); + +/* function declared in ajeutil.c */ +extern int Anlogic_GetBit(unsigned char* data, int id); +extern void Anlogic_SetBit(unsigned char* data, int id, int val); +extern char* Anlogic_HexStrToBinStr(char* src_str, int bin_len); + +/* function declared in vec.c */ +extern enum TAP_STATE Anlogic_TapState(unsigned char opcode); +extern const char* Anlogic_TapState2Str(enum TAP_STATE tap_state); +extern void Anlogic_SetEndDRState(enum TAP_STATE end_st); +extern void Anlogic_SetEndIRState(enum TAP_STATE end_st); +extern int Anlogic_TapTransist(enum TAP_STATE state); +extern int Anlogic_ExeSirCommand(unsigned char command, int cur_lvl, int total_lvl); +extern int Anlogic_ExeSdrCommand(unsigned int data_size, int cur_lvl, int total_lvl, + unsigned char* tdi_data, unsigned char* tdo_data); +extern void Anlogic_Init(void); +extern void Anlogic_ProcessRunTestTck(int num); +extern int Anlogic_SendData(unsigned char* tdi_data, unsigned int data_size, int cascade); +extern int Anlogic_SaveData(unsigned char* tdi_data, unsigned int data_size, unsigned char** tdo_data); +extern int Anlogic_ProcessShiftCmd(unsigned int op_code, unsigned int cascade, unsigned int read, unsigned int data_size, + unsigned char* tdi_data, unsigned char* tdo_data, unsigned char* mask); + +/* function forward declaration */ +int Anlogic_ExeSirCommands(unsigned int data_size, unsigned char* tdi_data, unsigned char* tdo_data, unsigned char* mask); +int Anlogic_ExeSDRCommands(unsigned int cascade, unsigned int data_size, + unsigned char* tdi_data, unsigned char* tdo_data, unsigned char* mask); + +long Anlogic_ReadNumber() +{ + long number = 0; + char byte = 0, cnt = 0; + do { + byte = fgetc(g_aje_file); + if (byte == EOF) { break; } + number += (byte & 0x007F) << (7 * cnt); + cnt ++; + } while (byte & 0x0080); + return number; +} + +unsigned long Anlogic_ProcessRuntestCmd() +{ + unsigned long ulTime = 0; + unsigned long num = 0; + char opcode = 0; + // char pre_opcode = 0; + char done = 0; + + if (g_freq == 0) { + g_freq = 80000; + } + + do { + //pre_opcode = opcode; + opcode = fgetc(g_aje_file); + switch (opcode) { + case TCK: + num = Anlogic_ReadNumber(); + if (num > 0x8000) { num -= 0x8000; } + ulTime += num; + ulTime -= 10; + break; + case WAIT: + num = Anlogic_ReadNumber(); + num -= 10; + if (num > 0x8000) { + num -= 0x8000; + num = g_freq * num / 1000; + } else { + num = g_freq * num / 1000000; + } + //if(TCK == pre_opcode){ + // ulTime = 0; + //} + ulTime += num; + break; + case RUNTEST: + break; + default: + done = 1; + break; + } + } while (!done); + + if (opcode == BEGINLINE) { + fseek(g_aje_file, -1, SEEK_CUR); + } + + //ulTime = 1200; + return ulTime; +} + +unsigned char* Anlogic_ProcessData(unsigned int byte_num) { + unsigned int index = 0; + unsigned char* data = NULL; + char mode = '\0'; + + if (s_compress == (char)FULL_MODE) { + data = (unsigned char*)calloc((byte_num+1), sizeof(unsigned char)); + for(index = 0; index < byte_num; ++index) { + data[index] = fgetc(g_aje_file); + } + } else { // compress mode + mode = fgetc(g_aje_file); + if (mode == 0) { // no compress + data = (unsigned char*)calloc((byte_num+1), sizeof(unsigned char)); + for(index = 0; index < byte_num; ++index) { + data[index] = fgetc(g_aje_file); + } + } else if (mode == 1) { // byte compress + data = Anlogic_BytesDecode(byte_num); + } else if (mode == 2) { // nibble compress + data = Anlogic_NibbleDecode(byte_num); + } else if (mode == 3) { // huffman compress + data = Anlogic_HuffmanDecode(byte_num); + } else if (mode == 4) { // LZW compress + data = Anlogic_LzwDecode(byte_num); + } else { + assert(0 && "Error: Unkown compress mode."); + } + } + return data; +} + +void Anlogic_PrintData(unsigned int byte_size, unsigned char* data) { + int byte_id = 0; + unsigned int bit_id = 0; + unsigned char byte = '\0'; + unsigned char flip_byte = '\0'; + + printf( " (" ); + for(byte_id = byte_size-1; byte_id >=0; --byte_id) { + byte = data[byte_id]; + flip_byte = 0x00; + for (bit_id = 0; bit_id < 8; bit_id++) { + flip_byte <<= 1; + if (byte & 0x1) { + flip_byte |= 0x1; + } + byte >>= 1; + } + printf("%02X", flip_byte); + } + printf(") "); +} + +/* Get the SIR Instruction */ +unsigned char Anlogic_ParseSirIns(unsigned int len, unsigned char* tdi_data) { + /* default value : bypass instruction */ + unsigned char sir_ins = INS_BYPASS; + + unsigned int byte_id = 0; + unsigned int bit_id = 0; + unsigned char byte = '\0'; + unsigned char flip_byte = '\0'; + + if (len % 8 != 0) { + return sir_ins; + } + + for(byte_id = 0; byte_id < len/8; ++byte_id) { + byte = tdi_data[byte_id]; + flip_byte = 0x00; + for (bit_id = 0; bit_id < 8; bit_id++) { + flip_byte <<= 1; + if (byte & 0x1) { + flip_byte |= 0x1; + } + byte >>= 1; + } + + if (flip_byte != INS_BYPASS) { + sir_ins = flip_byte; + break; + } + } + + return sir_ins; +} + +/* read the head and trailer bit number in sir instruction */ +int Anlogic_ReadSirInfo(int* header_num, int* trailer_num) { + unsigned int bin_num = 0; + unsigned int flip_byte = 0; + unsigned int bit_id = 0; + + int byte_id = 0; + int byte_num = 0; + + int* tmp_val = trailer_num; + + unsigned char* tdi = NULL; + char byte = '\0'; + + *header_num = 0; + *trailer_num = 0; + + bin_num = Anlogic_ReadNumber(); + byte_num = bin_num / 8; + if (bin_num % 8 != 0) { + byte_num++; + } + + if (fgetc(g_aje_file) != TDI) { + printf("Error Invalid format when executing read sir information!\n"); + fseek(g_aje_file, bin_num-1, SEEK_CUR); + return 0; + } + + tdi = Anlogic_ProcessData(byte_num); + for(byte_id = byte_num-1; byte_id >= 0; --byte_id) { + byte = tdi[byte_id]; + flip_byte = 0x00; + for (bit_id = 0; bit_id < 8; bit_id++) { + flip_byte <<= 1; + if (byte & 0x1) { + flip_byte |= 0x1; + } + byte >>= 1; + } + + if (flip_byte == BYPASS) { + *tmp_val += 1; + } else if (flip_byte != BYPASS) { + tmp_val = header_num; + if(flip_byte == IDCODE_PUB_2) { + s_idcode_pub = IDCODE_PUB_2; + } + } + } + + if (CONTINUE != fgetc(g_aje_file)) { + printf("Error Invalid format when executing read sir information!\n"); + return 0; + } + + return (tmp_val == trailer_num) ? 0 : 1; +} + +int Anlogic_ProcessShiftCommand(char op_code) +{ + int rtn_val = AJE_OK; + int id = 0; + unsigned int bin_num = 0; + unsigned int byte_num = 0; + unsigned char* tdi = NULL; + unsigned char* tdo = NULL; + unsigned char* msk = NULL; + unsigned char ins = 0xFF; + char byte = '\0'; + + bin_num = Anlogic_ReadNumber(); + byte_num = bin_num / 8; + if (bin_num % 8 != 0) { + byte_num++; + } + + while((byte = fgetc(g_aje_file)) != CONTINUE) { + switch (byte) { + case TDI: + tdi = Anlogic_ProcessData(byte_num); + break; + case TDO: + tdo = Anlogic_ProcessData(byte_num); + break; + case MASK: + msk = Anlogic_ProcessData(byte_num); + break; + default: + printf("Error: Invalid format when executing process sir or sdr instruction!\n"); + return AJE_INVALID_COMMAND; + break; + } + } + + /* exe sir or sdr instruction */ + if (op_code == SIR) { + + /* if done=0, 'refresh' must be executed before 'program_spi' */ + if (s_done_status == 0 && s_find_refresh_ins == 0) { + ins = Anlogic_ParseSirIns(bin_num, tdi); + if (ins == INS_REFRESH) { + s_find_refresh_ins = 1; + } else if (ins == INS_PROG_SPI) { +#ifdef AJE_DEBUG + printf("SIR %d TDI (", s_total_level*8); + for (id = 1; id <= s_total_level; ++id) { + if (id == s_cur_level) { + printf("%02X", INS_REFRESH); + } else { + printf("FF"); + } + } + printf(") ;\n"); + printf("SIR %d TDI (", s_total_level*8); + + for (id = 1; id <= s_total_level; ++id) { + printf("FF"); + } + printf(") ;\n"); +#endif + Anlogic_ExeSirCommand(INS_REFRESH, s_cur_level, s_total_level); + Anlogic_ExeSirCommand(INS_BYPASS, s_cur_level, s_total_level); + s_done_status = 1; + } + } + +#ifdef AJE_DEBUG + printf("SIR %d TDI", bin_num); + Anlogic_PrintData(byte_num, tdi); + if (tdo != NULL) { + printf("TDO"); + Anlogic_PrintData(byte_num, tdo); + } + if (msk != NULL) { + printf("MASK"); + Anlogic_PrintData(byte_num, msk); + } + printf(";\n"); +#endif + + rtn_val = Anlogic_ExeSirCommands(bin_num, tdi, tdo, msk); + } else { + +#ifdef AJE_DEBUG + printf("SDR %d TDI", bin_num); + Anlogic_PrintData(byte_num, tdi); + if (tdo != NULL) { + printf("TDO"); + Anlogic_PrintData(byte_num, tdo); + } + if (msk != NULL) { + printf("MASK"); + Anlogic_PrintData(byte_num, msk); + } + printf(";\n"); +#endif + + rtn_val = Anlogic_ExeSDRCommands(s_cascade, bin_num, tdi, tdo, msk); + } + + //free tdi tdo msk + if (tdi != NULL) { free(tdi); tdi = NULL; } + if (tdo != NULL) { free(tdo); tdo = NULL; } + if (msk != NULL) { free(msk); msk = NULL; } + + return rtn_val; +} + +int Anlogic_ProcessBypassCommand(char op_code) { + unsigned int bin_num = 0; + unsigned int byte_num = 0; + unsigned int index = 0; + + unsigned char* tdi = NULL; + char byte = '\0'; + + char* op_code_str = NULL; + + bin_num = Anlogic_ReadNumber(); + if (bin_num > 0) { + byte_num = bin_num / 8; + if (bin_num % 8 != 0) { + byte_num++; + } + byte = fgetc(g_aje_file); + if (byte == TDI) { + tdi = (unsigned char*)calloc((byte_num+1), sizeof(unsigned char)); + for(index = 0; index < byte_num; ++index) { + tdi[index] = fgetc(g_aje_file); + } + } + } + + switch (op_code) + { + case TIR: op_code_str = "TIR"; g_tir_size = bin_num; g_tir_data = tdi; break; + case TDR: op_code_str = "TDR"; g_tdr_size = bin_num; g_tdr_data = tdi; break; + case HIR: op_code_str = "HIR"; g_hir_size = bin_num; g_hir_data = tdi; break; + case HDR: op_code_str = "HDR"; g_hdr_size = bin_num; g_hdr_data = tdi; break; + default: + printf("Error: invalid Head/Trailer format, unkown opcode.\n\n"); + return AJE_INVALID_COMMAND; + } + +#ifdef AJE_DEBUG + printf("%s %d", op_code_str, bin_num); + if ( bin_num > 0) { + printf(" TDI "); + Anlogic_PrintData(byte_num, tdi); + } + printf(" ;\n"); +#endif + + if (bin_num > 0) { // Skip CONTINUE command + fgetc(g_aje_file); + } + return AJE_OK; +} + +int Anlogic_ExeSirCommands(unsigned int data_size, unsigned char* tdi_data, unsigned char* tdo_data, + unsigned char* mask) { + unsigned int rtn_val = AJE_OK; + unsigned int op_code = SIR; + unsigned int cascade = 0; // no casecade + unsigned int read = 0; // send data only + rtn_val = Anlogic_ProcessShiftCmd(op_code, cascade, read, data_size, tdi_data, tdo_data, mask); + return rtn_val; +} + +int Anlogic_ExeSDRCommands(unsigned int cascade, unsigned int data_size, + unsigned char* tdi_data, unsigned char* tdo_data, unsigned char* mask) { + unsigned int rtn_val = AJE_OK; + unsigned int op_code = SDR; + unsigned int read = 0; // send data only + rtn_val = Anlogic_ProcessShiftCmd(op_code, cascade, read, data_size, tdi_data, tdo_data, mask); + return rtn_val; +} + +/* + * read the aje header information, + * include crc, version, compress mode, maximum memory size and vendor +*/ +int Anlogic_ReadAjeHeader() +{ + char byte; + char buffer[100]; + int i; + printf("Anlogic_ReadAjeHeader start.\n"); + // crc bytes + if (fgetc(g_aje_file) != FILECRC) { + return AJE_FILE_INVALID; + } + + if (fgets(g_aje_crc, 3, g_aje_file) == NULL) { + return AJE_FILE_INVALID; + } + else { + printf("g_aje_crc[0] = 0x%02x, g_aje_crc[1] = 0x%02x, g_aje_crc[2] = 0x%02x,\n", + g_aje_crc[0],g_aje_crc[1],g_aje_crc[2]); + } + + // version + if (fgets(buffer, 9, g_aje_file) == NULL) { + return AJE_FILE_INVALID; + } + else + { + for(int i=0;i<9;i++) + printf("buffer[%d] = 0x%02x ",i,buffer[i]); + printf("\n"); + } + + // compress or full + byte = fgetc(g_aje_file); + if (byte != (char)COMP_MODE && byte != (char)FULL_MODE) { + return AJE_FILE_INVALID; + } + else + printf("byte = 0x%02x ",byte); + s_compress = byte; + + // maximum memory size + if (MEM != fgetc(g_aje_file)) { + return AJE_FILE_INVALID; + } + Anlogic_ReadNumber(); + + // Vender + if (VENDOR != fgetc(g_aje_file )) { + return AJE_FILE_INVALID; + } + if (ANLOGIC != fgetc(g_aje_file)) {; + return AJE_FILE_INVALID; + } + + s_cfg_start_pos = ftell(g_aje_file); + + printf("Anlogic_ReadAjeHeader end.\n"); + + return AJE_OK; +} + +/* read the chip id before processing data, need to get the chain information */ +int Anlogic_ReadChipIdcode(void) +{ + int rtn_val = AJE_OK; + int finish = 0; + + /* get from HDR/TDR Command */ + int hdr_num = 0; + int tdr_num = 0; + + /* get from SIR Command */ + int trailer_num = 0; + int header_num = 0; + + long line_length = 0; + char op_code = 0x00; + + printf("Anlogic_ReadChipIdcode start.\n"); + while((finish == 0) && (fgetc(g_aje_file)) == BEGINLINE) { + line_length = Anlogic_ReadNumber()/8; + printf("Anlogic_ReadNumber()/8 = %d.\n",line_length); + op_code = fgetc(g_aje_file); + printf("op_code = 0x%02x.\n",op_code); + switch (op_code) { + case HDR: + printf("Acase HDR.\n"); + hdr_num = Anlogic_ReadNumber(); + if (hdr_num != 0) { + while (CONTINUE != fgetc(g_aje_file)); + } + break; + case TDR: + printf("Acase TDR.\n"); + tdr_num = Anlogic_ReadNumber(); + if (tdr_num != 0) { + while (CONTINUE != fgetc(g_aje_file)); + } + break; + case SIR: + printf("Acase SIR.\n"); + finish = Anlogic_ReadSirInfo(&header_num, &trailer_num); + break; + default: + printf("Acase default.\n"); + fseek(g_aje_file, line_length-1, SEEK_CUR); + break; + } + } + + if (finish == 0) { + return AJE_WARNING; + } + + s_cur_level = tdr_num+trailer_num+1; + s_total_level = tdr_num+trailer_num+1+header_num+hdr_num; + + rtn_val = Anlogic_ExeSirCommand(s_idcode_pub, s_cur_level, s_total_level); + if (rtn_val != AJE_OK) { + return rtn_val; + } + + unsigned char* tdo_data = (unsigned char*)malloc(5*sizeof(unsigned char)); + tdo_data[4] = '\0'; + rtn_val = Anlogic_ExeSdrCommand(32, s_cur_level, s_total_level, NULL, tdo_data); + if (rtn_val == AJE_OK) { /* print 32 bit chip id in terminal */ + if (tdo_data[0] == 0 && tdo_data[1] == 0 && + tdo_data[2] == 0 && tdo_data[3] == 0) { + printf("Error: Chip validation failed, please check the connection.\n"); + rtn_val = AJE_ERROR; + } else { + printf("\n Chip Id : "); + Anlogic_PrintData(4, tdo_data); + printf("\n"); + } + } + free(tdo_data); + tdo_data = NULL; + printf("Anlogic_ReadChipIdcode end.\n"); + return rtn_val; +} + +/* Loading Read chip io status instrcution and compare ref_io_status */ +int Anlogic_LoadingReadChipIOStatusInstruction(unsigned int bit_size, unsigned char* ref_io_status) { + int rtn_val = AJE_OK; + int bit = 0; + unsigned int io_index = 0; + unsigned int byte = (bit_size+7)/8; + + rtn_val = Anlogic_ExeSirCommand(SAMPLE, s_cur_level, s_total_level); + if (rtn_val != AJE_OK) { + return rtn_val; + } + + unsigned char* tdo_data = (unsigned char*)malloc((byte+1)*sizeof(unsigned char)); + tdo_data[byte] = '\0'; + rtn_val = Anlogic_ExeSdrCommand(bit_size, s_cur_level, s_total_level, NULL, tdo_data); + if (rtn_val == AJE_OK) { + printf("\nIO Status: \n"); + printf("Bs order\t\tRef\t\tRead\t\tVerify\n"); + + for (io_index = 0; io_index < bit_size; ++io_index) { + bit = Anlogic_GetBit(tdo_data, io_index); + printf("%8d\t\t%c\t\t%d\t\t", io_index, ref_io_status[io_index], bit); + if (ref_io_status[io_index] - '0' == bit) { + printf("true\n"); + } else { + printf("false\n"); + } + } + } + + free(tdo_data); + tdo_data = NULL; + return rtn_val; +} + +int Anlogic_ReadChipIOStatus(char* io_state_file) { + int rtn_val = AJE_OK; + FILE* io_stat_stream = NULL; + char line[LINE_MAX_SIZE]; + char buf[10]; + int sscanf_num = 0; + char sdr_tdi_str[DATA_MAX_SIZE]; + char sdr_tdo_str[DATA_MAX_SIZE]; + char sdr_mask_str[DATA_MAX_SIZE]; + + char* sdr_tdo_bin_str = NULL; + char* sdr_mask_bin_str = NULL; + unsigned char* ref_io_status = NULL; + + int sir_num = 0; + int sir_val = 0; + int sdr_num = 0; + int str_idx = 0; + + int find_sample_ins = 0; /* sample instruction flag */ + + char* p = strstr(io_state_file, ".svf"); + if (p == NULL || strcmp(p, ".svf") != 0) { + printf("Error: %s is not a svf file\n", io_state_file); + return AJE_FILE_INVALID; + } + + if ((io_stat_stream = fopen(io_state_file, "r")) == NULL) { + printf("Error: cannot read the svf file %s\n", io_state_file); + return AJE_FILE_OPEN_FAIL; + } + + // Parse svf file + while (!feof(io_stat_stream)) { + fgets(line, LINE_MAX_SIZE, io_stat_stream); + + // Find "Sample" instruction, E.G. SIR 8 TDI (05) + if (find_sample_ins == 0) { + sscanf_num = sscanf(line, "SIR %d TDI (%d)", &sir_num, &sir_val); + if (sscanf_num != 2) { continue; } + if (sir_num != 8 || sir_val != INS_SAMPLE) { + continue; + } + find_sample_ins = 1; + } else { + if (strncasecmp(line, "SDR", 3) != 0) { + continue; + } + // sample instruction + // E.G. SDR 426 TDI (3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + // TDO (3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBAFBFEAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + // MASK (0000000000000000000000000000000000000000000000AAAAAAAA00000000000000000000000000000000000000000000000000000); + sscanf_num = sscanf(line, "SDR %d TDI (%[^)]) TDO (%[^)]) MASK (%[^)])", &sdr_num, sdr_tdi_str, sdr_tdo_str, sdr_mask_str); + if (sscanf_num == 2) { // for line feeds + fgets(line, LINE_MAX_SIZE, io_stat_stream); + sscanf_num = sscanf(line, "%s (%[^)])", buf, sdr_tdo_str); + assert(strcasecmp(buf, "TDO") == 0); + if (sscanf_num == 2) { + fgets(line, LINE_MAX_SIZE, io_stat_stream); + sscanf_num = sscanf(line, "%s (%[^ )])", buf, sdr_mask_str); + assert(strcasecmp(buf, "MASK") == 0); + } + } + + if (sdr_num == 0 || sdr_tdi_str == NULL || sdr_tdo_str == NULL || sdr_mask_str == NULL) { + printf("Error: Invalid SDR string %s", line); + return AJE_FILE_INVALID; + } + + ref_io_status = (unsigned char*)malloc((sdr_num+1)*sizeof(unsigned char)); + memset(ref_io_status, 'x', sdr_num); + ref_io_status[sdr_num] = 0x00; + + sdr_tdo_bin_str = Anlogic_HexStrToBinStr(sdr_tdo_str, sdr_num); + sdr_mask_bin_str = Anlogic_HexStrToBinStr(sdr_mask_str, sdr_num); + + for(str_idx = 0; str_idx < sdr_num; ++str_idx) { + if (sdr_mask_bin_str[str_idx] == '1') { // the bit need verify + ref_io_status[sdr_num-1-str_idx] = sdr_tdo_bin_str[str_idx]; + } + } + } // end read sdr instruction + } // end of read file + + if (ref_io_status == NULL) { + printf("Error: Invalid svf file %s, cannot find the sample data", io_state_file); + return AJE_FILE_INVALID; + } + + if (sdr_tdo_bin_str != NULL) { free(sdr_tdo_bin_str); sdr_tdo_bin_str = NULL; } + if (sdr_mask_bin_str != NULL) { free(sdr_mask_bin_str); sdr_mask_bin_str = NULL; } + + rtn_val = Anlogic_LoadingReadChipIOStatusInstruction(sdr_num, ref_io_status); + + return rtn_val; +} + +int Anlogic_CheckDonePinStatus() { + int rtn_val = AJE_OK; + unsigned char* tdo_data = NULL; + + s_done_status = 1; + rtn_val = Anlogic_ExeSirCommand(INS_READ_STATUS, s_cur_level, s_total_level); + + tdo_data = (unsigned char*)malloc(5*sizeof(unsigned char)); + tdo_data[4] = '\0'; + rtn_val = Anlogic_ExeSdrCommand(32, s_cur_level, s_total_level, NULL, tdo_data); + if (rtn_val == AJE_OK) { + s_done_status = Anlogic_GetBit(tdo_data, 26); + } + + free(tdo_data); + tdo_data = NULL; + return rtn_val; +} + +/* core function, parse aje file and process data */ +int Anlogic_ProcessCmd() { + int rtn_val = AJE_OK; + int tck_num = 0; /* for runtest num tck command */ + int loop_num = 0; /* for loop command */ + long cmd_length = 0; + long cur_pos = 0; + long freq = 0; + char op_code = '\0'; + + enum TAP_STATE tap_state = TAP_RESET; + + fseek(g_aje_file, s_cfg_start_pos, SEEK_SET); /* restore to the start position of configuration */ + + while((fgetc(g_aje_file)) == BEGINLINE) { + cmd_length = Anlogic_ReadNumber()/8; + + op_code = fgetc(g_aje_file); + switch (op_code) { + case STATE: + tap_state = Anlogic_TapState(fgetc(g_aje_file)); + Anlogic_TapTransist(tap_state); + if (cmd_length == 2) { + printf("STATE %s;\n", Anlogic_TapState2Str(tap_state)); + } + if (cmd_length >= 2 && tap_state == TAP_IDLE) { + tck_num = Anlogic_ProcessRuntestCmd(); + if (tck_num > 0) { + Anlogic_ProcessRunTestTck(tck_num); + } + } + break; + case FREQUENCY: + freq = Anlogic_ReadNumber(); + if (g_freq == 0 || g_freq > freq) { + g_freq = freq; +#ifdef AJE_DEBUG + printf("FREQUENCY %.2E HZ;\n", (float)g_freq); +#endif + } + break; + case SIR: + case SDR: + rtn_val = Anlogic_ProcessShiftCommand(op_code); + break; + case LOOP: + loop_num = Anlogic_ReadNumber(); + cur_pos = ftell(g_aje_file); + break; + case ENDLOOP: + if (loop_num > 1) { + fseek(g_aje_file, cur_pos, SEEK_SET); + loop_num--; + } + break; + case TDR: + case TIR: + case HDR: + case HIR: + rtn_val = Anlogic_ProcessBypassCommand(op_code); + break; + case ENDIR: + tap_state = Anlogic_TapState(fgetc(g_aje_file)); + Anlogic_SetEndIRState(tap_state); + break; + case ENDDR: + tap_state = Anlogic_TapState(fgetc(g_aje_file)); + Anlogic_SetEndDRState(tap_state); + break; + case SETFLOW: + if (fgetc(g_aje_file) == CASCADE) { + s_cascade = 1; + } + break; + case RESETFLOW: + if (fgetc(g_aje_file) == CASCADE) { + s_cascade = 0; + } + break; + case TRST: + if (fgetc(g_aje_file) == ON) { + printf("TRST ON;\n"); + } else { + printf("TRST OFF;\n"); + } + break; + case RUNTEST: + { + fseek(g_aje_file, cmd_length-1, SEEK_CUR); + } + break; + default: + printf("Error: invalid file format, unkown opcode.\n\n"); + return AJE_INVALID_COMMAND; + } + + if (rtn_val != AJE_OK) { + return rtn_val; + } + } + return rtn_val; +} + + +int Anlogic_AjeToVec(const char* aje_file) { + int rtn_code = AJE_OK; + char* io_state_file = NULL; /* input svf file, use to read io status */ + + if ((g_aje_file = fopen(aje_file, "rb")) == NULL) { + return AJE_FILE_OPEN_FAIL; + } + else + printf("fopen %s sucess,file * = %p.\n",aje_file,g_aje_file); + + /* read header content */ + rtn_code = Anlogic_ReadAjeHeader(); + if (rtn_code != AJE_OK) { + return rtn_code; + } + + /* execute "state reset" first, 2019/12/20 */ + Anlogic_Init(); + + /* read chip id code */ + rtn_code = Anlogic_ReadChipIdcode(); + if (rtn_code != AJE_OK) { + return rtn_code; + } + + /* read io status */ + if (io_state_file != NULL) { + rtn_code = Anlogic_ReadChipIOStatus(io_state_file); + if (rtn_code != AJE_OK) { + return rtn_code; + } + } + + /* check done pin status */ + Anlogic_CheckDonePinStatus(); + + /* core process function */ + rtn_code = Anlogic_ProcessCmd(); + + fclose(g_aje_file); + return rtn_code; +} diff --git a/device/gxx-linux/motorboard/ajeutil.cpp b/device/gxx-linux/motorboard/ajeutil.cpp new file mode 100644 index 0000000..0cb7cc3 --- /dev/null +++ b/device/gxx-linux/motorboard/ajeutil.cpp @@ -0,0 +1,101 @@ +/******************************************************************* +* Copyright (c) 2011 -2021 Anlogic Inc. + * The Software is distributed in source code form and is open to + * re-distribution and modification where applicable +*******************************************************************/ + +/******************************************************************* + Filename : ajeutil.c + Description: utility source file + Log: initial version, December 2019 +*******************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include + +int Anlogic_GetBit(unsigned char* data, int id) { + return (data[id/8] & (1 << (7-id%8))) ? 1 : 0; +} + +void Anlogic_SetBit(unsigned char* data, int id, int val) { + unsigned char mask = 1 << (7-id%8); + if (val) { + data[id/8] |= mask; + } else { + data[id/8] &= ~mask; + } +} + +/* reverse char data e.g. 8'b10001101 -> 8'b10110001 */ +unsigned char Anlogic_ReverseChar(unsigned char byte) { + unsigned int bit_id = 0; + unsigned char flip_byte = 0x00; + for (bit_id = 0; bit_id < 8; ++bit_id) { + flip_byte <<= 1; + if (byte & 0x1) { + flip_byte |= 0x1; + } + byte >>= 1; + } + return flip_byte; +} + +/* tranfer hex to bin data, e.g. char('A') -> char[4] = {'1', '0', '1', '0' } */ +void Anlogic_HexTobin(char hex, char* char_s) { + switch(hex) { + case '0': strcpy(char_s ,"0000"); break; + case '1': strcpy(char_s ,"0001"); break; + case '2': strcpy(char_s ,"0010"); break; + case '3': strcpy(char_s ,"0011"); break; + case '4': strcpy(char_s ,"0100"); break; + case '5': strcpy(char_s ,"0101"); break; + case '6': strcpy(char_s ,"0110"); break; + case '7': strcpy(char_s ,"0111"); break; + case '8': strcpy(char_s ,"1000"); break; + case '9': strcpy(char_s ,"1001"); break; + case 'a': + case 'A': strcpy(char_s ,"1010"); break; + case 'b': + case 'B': strcpy(char_s ,"1011"); break; + case 'c': + case 'C': strcpy(char_s ,"1100"); break; + case 'd': + case 'D': strcpy(char_s ,"1101"); break; + case 'e': + case 'E': strcpy(char_s ,"1110"); break; + case 'f': + case 'F': strcpy(char_s ,"1111"); break; + default: + printf("Error: HexToChar Invalid Hex value %c", hex); + } +} + +char* Anlogic_HexStrToBinStr(char* src_str, int bin_len) { + char* bin_value = NULL; + int hex_idx = 0; + int char_idx = 0; + char char_s[5] = { 0 }; + int hex_size = strlen(src_str); + if (hex_size*4 < bin_len) { + return NULL; + } + bin_value = (char*)malloc((bin_len+1)*sizeof(char)); + bin_value[bin_len] = 0x00; + + for(hex_idx=hex_size-1; hex_idx>=0; --hex_idx) { + char c = src_str[hex_idx]; + Anlogic_HexTobin(c, char_s); + for (char_idx = 0; char_idx<4; ++char_idx) { + bin_value[--bin_len] = char_s[3-char_idx]; + if (bin_len == 0) { + return bin_value; + } + } // end char_idx + } // end hex_idx + return bin_value; +} + diff --git a/device/gxx-linux/motorboard/decodel.cpp b/device/gxx-linux/motorboard/decodel.cpp new file mode 100644 index 0000000..c93a6d0 --- /dev/null +++ b/device/gxx-linux/motorboard/decodel.cpp @@ -0,0 +1,155 @@ +/******************************************************************* +* Copyright (c) 2011 -2021 Anlogic Inc. + * The Software is distributed in source code form and is open to + * re-distribution and modification where applicable +*******************************************************************/ + +/*********************************************************************** +Filename: decode.c +Description: decode the data from aje file +Log: initial version, July 2019 + ***********************************************************************/ + +#include +#include +#include + +extern FILE* g_aje_file; + +/* Function delcared in lzw_lib.c */ +extern int lzw_decompress (void (*dst)(int), int (*src)(void)); + +unsigned char* g_pWriteBuffer = NULL; +long int g_iWriteCount = 0; + +void Anlogic_WriteBufferByte(int byte) +{ + g_pWriteBuffer[g_iWriteCount++] = (unsigned char)byte; +} + +int Anlogic_ReadAjeByte(void) +{ + return fgetc(g_aje_file); +} + +long Anlogic_NumberDecode(void) { + long number = 0; + char byte = '\0'; + unsigned int count = 0; + do { + byte = fgetc(g_aje_file); + number += (byte & 0x7F) << (7 * count++); + } while (byte & 0x80); + return number; +} + +unsigned char* Anlogic_BytesDecode(long bytes) { + long int i = 0; + long int key_count = 0; + unsigned char byte = 0, key = 0; + unsigned char* rtn_val = NULL; + rtn_val = (unsigned char*)malloc((bytes+1)*sizeof(unsigned char)); + + key = fgetc(g_aje_file); + + for (i = 0; i < bytes; i++) { + if (key_count <= 0) { + byte = fgetc(g_aje_file); + rtn_val[i] = byte; + if (byte == key) { + key_count = Anlogic_NumberDecode(); // The number of key bytes + } + } else { + key_count--; // Use up the key chain first + rtn_val[i] = key; + } + } + return rtn_val; +} + +unsigned char* Anlogic_NibbleDecode(long bytes) { + int i = 0, j = 0, byte_time = 0; + long int num_keys = 0, key_bytes, key_times; + unsigned char *buffer = 0; + unsigned char* rtn_val; + rtn_val = (unsigned char*)malloc((bytes+1)*sizeof(unsigned char)); + + num_keys = Anlogic_NumberDecode(); + key_bytes = (num_keys + 1) / 2; + key_times = (bytes * 2) / num_keys; + buffer = (unsigned char*)calloc(key_bytes + 1 , sizeof(unsigned char)); + if (!buffer) { + assert(0 && "nibble decode: calloc fail"); + } + + for (i = 0; i < key_bytes; i++ ) + buffer[i] = fgetc(g_aje_file); + + if (num_keys % 2 == 0) { + for ( i = 0; i < key_times; i++ ) { + for ( j = 0; j < key_bytes; j++ ) { + rtn_val[j+i*key_bytes] = buffer[j]; + } + } + } else { + assert(key_times % 2 == 0); + buffer = (unsigned char*)realloc(buffer, key_bytes*2*sizeof(unsigned char)); + if (!buffer) { + assert(0 && "nibble decode: realloc fail"); + } + //buffer[key_bytes-2 : 0] keep no change + for(i = key_bytes-1; i < key_bytes*2-1; ++i) { + if (i == key_bytes-1) + buffer[i] = (buffer[i] & 0xF0) + (buffer[0] >> 4); + else + buffer[i] = ((buffer[i-key_bytes] << 4) & 0xF0) + + (buffer[i-key_bytes+1] >> 4); + } + byte_time = key_times / 2; + for(i = 0; i < byte_time; ++i) { + for(j = 0; j < (key_bytes*2-1); ++j) { + rtn_val[j+i*(key_bytes*2-1)] = buffer[j]; + } + } + } + return rtn_val; +} + +unsigned char* Anlogic_HuffmanDecode(long bytes) { + int i = 0, j = 0, m = 0, bits = 8; + unsigned char cur_char = 0, key = 0, byte = 0; + unsigned char* rtn_val; + rtn_val = (unsigned char*)malloc((bytes+1)*sizeof(unsigned char)); + + key = fgetc(g_aje_file); + + for ( i = 0; i < bytes; i++ ) { + byte = 0x00; + if ( bits > 7 ) { + cur_char = fgetc(g_aje_file); + bits = 0; + } + if ( ( cur_char << bits++ ) & 0x80 ) { + m = 8; + for (j = 0; j < m; j++) { + if (bits > 7) { + cur_char = fgetc(g_aje_file); + bits = 0; + } + byte |= ( ( cur_char << bits++ ) & 0x80 ) >> j; + } + } else { + byte = key; + m = 0; + } + rtn_val[i] = byte; + } + return rtn_val; +} + +unsigned char* Anlogic_LzwDecode(long bytes) { + g_pWriteBuffer = (unsigned char*)malloc((bytes+1)*sizeof(unsigned char)); + g_iWriteCount = 0; + lzw_decompress(Anlogic_WriteBufferByte, Anlogic_ReadAjeByte); + return g_pWriteBuffer; +} diff --git a/device/gxx-linux/motorboard/jtagupdata.cpp b/device/gxx-linux/motorboard/jtagupdata.cpp new file mode 100644 index 0000000..a65a07d --- /dev/null +++ b/device/gxx-linux/motorboard/jtagupdata.cpp @@ -0,0 +1,26 @@ +#include "jtagupdata.h" +#include "aje2vec.cpp" +JtagUp::JtagUp(std::string file):filepath(file){ + m_state = 0; +} +JtagUp::~JtagUp(){ + if(is_uping()) + m_fu.get(); +} +void JtagUp::startup(){ + if(is_uping()) + return; + m_state = 0; + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + m_fu = std::async(std::launch::async,&JtagUp::upfc,this); +} +bool JtagUp::is_uping() +{ + return m_fu.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout; +} +int JtagUp::getresult(){ + return m_state; +} +void JtagUp::upfc(){ + m_state = Anlogic_AjeToVec(filepath.c_str()); +} \ No newline at end of file diff --git a/device/gxx-linux/motorboard/jtagupdata.h b/device/gxx-linux/motorboard/jtagupdata.h new file mode 100644 index 0000000..aec9287 --- /dev/null +++ b/device/gxx-linux/motorboard/jtagupdata.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include +#include +#include "Jtag.h" +#include "opcode.h" +#include +#include + +class JtagUp{ +public: + JtagUp(std::string file); + ~JtagUp(); + void startup(); + bool is_uping(); + int getresult(); +private: + void upfc(); + volatile int m_state; + std::future m_fu; + std::string filepath; +}; \ No newline at end of file diff --git a/device/gxx-linux/motorboard/lzw_lib.cpp b/device/gxx-linux/motorboard/lzw_lib.cpp new file mode 100644 index 0000000..cf3701a --- /dev/null +++ b/device/gxx-linux/motorboard/lzw_lib.cpp @@ -0,0 +1,353 @@ +//////////////////////////////////////////////////////////////////////////// +// **** LZW-AB **** // +// Adjusted Binary LZW Compressor/Decompressor // +// Copyright (c) 2016 David Bryant // +// All Rights Reserved // +// Distributed under the BSD Software License (see license.txt) // +//////////////////////////////////////////////////////////////////////////// + +//#define KERNEL_MODE +#ifdef KERNEL_MODE +#include +#include +#include +#include +#else +#include +#include +#include +#endif + + +/* This library implements the LZW general-purpose data compression algorithm. + * The algorithm was originally described as a hardware implementation by + * Terry Welsh here: + * + * Welch, T.A. “A Technique for High-Performance Data Compression.” + * IEEE Computer 17,6 (June 1984), pp. 8-19. + * + * Since then there have been enumerable refinements and variations on the + * basic technique, and this implementation is no different. The target of + * the present implementation is embedded systems, and so emphasis was placed + * on simplicity, fast execution, and minimal RAM usage. + * + * The symbols are stored in adjusted binary, which provides considerably + * better compression performance with virtually no speed penalty compared to + * the fixed sizes normally used. To ensure good performance on data with + * varying characteristics (like executable images) the encoder resets as + * soon as the dictionary is full. Also, worst-case performance is limited + * to about 8% inflation by catching poor performance and forcing an early + * reset before longer symbols are sent. + * + * The maximum symbol size is configurable on the encode side (from 9 bits + * to 12 bits) and determines the RAM footprint required by both sides and, + * to a large extent, the compression performance. This information is + * communicated to the decoder in the first stream byte so that it can + * allocate accordingly. The RAM requirements are as follows: + * + * maximum encoder RAM decoder RAM + * symbol size requirement requirement + * ----------------------------------------- + * 9-bit 1792 bytes 1024 bytes + * 10-bit 4352 bytes 3072 bytes + * 11-bit 9472 bytes 7168 bytes + * 12-bit 19712 bytes 15360 bytes + * + * This implementation uses malloc(), but obviously an embedded version could + * use static arrays instead if desired (assuming that the maxbits was + * controlled outside). + */ + +#define NULL_CODE -1 // indicates a NULL prefix +#define CLEAR_CODE 256 // code to flush dictionary and restart decoder +#define FIRST_STRING 257 // code of first dictionary string + +/* This macro writes the adjusted-binary symbol "code" given the maximum + * symbol "maxcode". A macro is used here just to avoid the duplication in + * the lzw_compress() function. The idea is that if "maxcode" is not one + * less than a power of two (which it rarely will be) then this code can + * often send fewer bits that would be required with a fixed-sized code. + * + * For example, the first code we send will have a "maxcode" of 257, so + * every "code" would normally consume 9 bits. But with adjusted binary we + * can actually represent any code from 0 to 253 with just 8 bits -- only + * the 4 codes from 254 to 257 take 9 bits. + */ + +#define WRITE_CODE(code,maxcode) do { \ + int code_bits = (maxcode) < 1024 ? \ + ((maxcode) < 512 ? 8 : 9) : \ + ((maxcode) < 2048 ? 10 : 11); \ + int extras = (1 << (code_bits + 1)) - (maxcode) - 1; \ + if ((code) < extras) { \ + shifter |= ((long)(code) << bits); \ + bits += code_bits; \ + } \ + else { \ + shifter |= ((long)(((code) + extras) >> 1) << bits); \ + bits += code_bits; \ + shifter |= ((long)(((code) + extras) & 1) << bits++); \ + } \ + do { (*dst)(shifter); shifter >>= 8; output_bytes++; \ + } while ((bits -= 8) >= 8); \ +} while (0) + +/* LZW compression function. Bytes (8-bit) are read and written through callbacks and the + * "maxbits" parameter specifies the maximum symbol size (9-12), which in turn determines + * the RAM requirement and, to a large extent, the level of compression achievable. A return + * value of EOF from the "src" callback terminates the compression process. A non-zero return + * value indicates one of the two possible errors -- bad "maxbits" param or failed malloc(). + */ + +int lzw_compress (void (*dst)(int), int (*src)(void), int maxbits) +{ + int next = FIRST_STRING, prefix = NULL_CODE, bits = 0, total_codes, c; + unsigned long input_bytes = 0, output_bytes = 0; + short *first_references, *next_references; + unsigned char *terminators; + unsigned long shifter = 0; + + if (maxbits < 9 || maxbits > 12) // check for valid "maxbits" setting + return 1; + + // based on the "maxbits" parameter, compute total codes and allocate dictionary storage + + total_codes = 1 << maxbits; +#ifdef KERNEL_MODE + first_references = ( short int * ) kmalloc (total_codes * sizeof (first_references [0])); + next_references = ( short int * ) kmalloc ((total_codes - 256) * sizeof (next_references [0])); + terminators = ( unsigned char * ) kmalloc ((total_codes - 256) * sizeof (terminators [0])); +#else + first_references = ( short int * ) malloc (total_codes * sizeof (first_references [0])); + next_references = ( short int * ) malloc ((total_codes - 256) * sizeof (next_references [0])); + terminators = ( unsigned char * ) malloc ((total_codes - 256) * sizeof (terminators [0])); +#endif + + if (!first_references || !next_references || !terminators) + return 1; // failed malloc() + + // clear the dictionary + + memset (first_references, 0, total_codes * sizeof (first_references [0])); + memset (next_references, 0, (total_codes - 256) * sizeof (next_references [0])); + memset (terminators, 0, (total_codes - 256) * sizeof (terminators [0])); + + (*dst)(maxbits - 9); // first byte in output stream indicates the maximum symbol bits + + // This is the main loop where we read input bytes and compress them. We always keep track of the + // "prefix", which represents a pending byte (if < 256) or string entry (if >= FIRST_STRING) that + // has not been sent to the decoder yet. The output symbols are kept in the "shifter" and "bits" + // variables and are sent to the output every time 8 bits are available (done in the macro). + + while ((c = (*src)()) != EOF) { + int cti; // coding table index + + input_bytes++; + + if (prefix == NULL_CODE) { // this only happens the very first byte when we don't yet have a prefix + prefix = c; + continue; + } + + if ((cti = first_references [prefix])) { // if any longer strings are built on the current prefix... + while (1) + if (terminators [cti - 256] == c) { // we found a matching string, so we just update the prefix + prefix = cti; // to that string and continue without sending anything + break; + } + else if (!next_references [cti - 256]) { // this string did not match the new character and + next_references [cti - 256] = next; // there aren't any more, so we'll add a new string + cti = 0; // and point to it with "next_reference" + break; + } + else + cti = next_references [cti - 256]; // there are more possible matches to check, so loop back + } + else // no longer strings are based on the current prefix, so now + first_references [prefix] = next; // the current prefix plus the new byte will be the next string + + // If "cti" is zero, we could not simply extend our "prefix" to a longer string because we did not find a + // dictionary match, so we send the symbol representing the current "prefix" and add the new string to the + // dictionary. Since the current byte "c" was not included in the prefix, that now becomes our new prefix. + + if (!cti) { + WRITE_CODE (prefix, next); // send symbol for current prefix (0 to next-1) + terminators [next - 256] = c; // newly created string has current byte as the terminator + prefix = c; // current byte also becomes new prefix for next string + + // This is where we bump the next string index and decide whether to clear the dictionary and start over. + // The triggers for that are either the dictionary is full or we've been outputting too many bytes and + // decide to cut our losses before the symbols get any larger. Note that for the dictionary full case we + // do NOT send the CLEAR_CODE because the decoder knows about this and we don't want to be redundant. + + if (++next == total_codes || output_bytes > 8 + input_bytes + (input_bytes >> 4)) { + if (next < total_codes) + WRITE_CODE (CLEAR_CODE, next); + + // clear the dictionary and reset the byte counters -- basically everything starts over + // except that we keep the last pending "prefix" (which, of course, was never sent) + + memset (first_references, 0, total_codes * sizeof (first_references [0])); + memset (next_references, 0, (total_codes - 256) * sizeof (next_references [0])); + memset (terminators, 0, (total_codes - 256) * sizeof (terminators [0])); + input_bytes = output_bytes = 0; + next = FIRST_STRING; + } + } + } + + // we're done with input, so if we've received anything we still need to send that pesky pending prefix... + + if (prefix != NULL_CODE) { + WRITE_CODE (prefix, next); + + if (++next == total_codes) // watch for clearing to the first string to stay in step with the decoder! + next = FIRST_STRING; // (this was actually a corner-case bug that did not trigger often) + } + + WRITE_CODE (next, next); // the maximum possible code is always reserved for our END_CODE + + if (bits) // finally, flush any pending bits from the shifter + (*dst)(shifter); + +#ifdef KERNEL_MODE + kfree (terminators); kfree (next_references); kfree (first_references); +#else + free (terminators); free (next_references); free (first_references); +#endif + return 0; +} + +/* LZW decompression function. Bytes (8-bit) are read and written through callbacks. The + * "maxbits" parameter is read as the first byte in the stream and controls how much memory + * is allocated for decoding. A return value of EOF from the "src" callback terminates the + * compression process (although this should not normally occur). A non-zero return value + * indicates an error, which in this case can be a bad "maxbits" read from the stream, a + * failed malloc(), or if an EOF is read from the input stream before the compression + * terminates naturally with END_CODE. + */ + +int lzw_decompress (void (*dst)(int), int (*src)(void)) +{ + int read_byte, next = FIRST_STRING, prefix = CLEAR_CODE, bits = 0, total_codes; + unsigned char *terminators, *reverse_buffer; + unsigned long shifter = 0; + short *prefixes; + + if ((read_byte = ((*src)())) == EOF || (read_byte & 0xfc)) //sanitize first byte + return 1; + + // based on the "maxbits" parameter, compute total codes and allocate dictionary storage + + total_codes = 512 << (read_byte & 0x3); +#ifdef KERNEL_MODE + reverse_buffer = ( unsigned char *) kmalloc ((total_codes - 256) * sizeof (reverse_buffer [0])); + prefixes = ( short * ) kmalloc ((total_codes - 256) * sizeof (prefixes [0])); + terminators = ( unsigned char * ) kmalloc ((total_codes - 256) * sizeof (terminators [0])); +#else + reverse_buffer = ( unsigned char *) malloc ((total_codes - 256) * sizeof (reverse_buffer [0])); + prefixes = ( short * ) malloc ((total_codes - 256) * sizeof (prefixes [0])); + terminators = ( unsigned char * ) malloc ((total_codes - 256) * sizeof (terminators [0])); +#endif + + if (!reverse_buffer || !prefixes || !terminators) // check for mallco() failure + return 1; + + // This is the main loop where we read input symbols. The values range from 0 to the code value + // of the "next" string in the dictionary (although the actual "next" code cannot be used yet, + // and so we reserve that code for the END_CODE). Note that receiving an EOF from the input + // stream is actually an error because we should have gotten the END_CODE first. + + while (1) { + int code_bits = next < 1024 ? (next < 512 ? 8 : 9) : (next < 2048 ? 10 : 11), code; + int extras = (1 << (code_bits + 1)) - next - 1; + + do { + if ((read_byte = ((*src)())) == EOF) { +#ifdef KERNEL_MODE + kfree (terminators); kfree (prefixes); kfree (reverse_buffer); +#else + free (terminators); free (prefixes); free (reverse_buffer); +#endif + return 1; + } + + shifter |= (long) read_byte << bits; + } while ((bits += 8) < code_bits); + + // first we assume the code will fit in the minimum number of required bits + + code = (int) shifter & ((1 << code_bits) - 1); + shifter >>= code_bits; + bits -= code_bits; + + // but if code >= extras, then we need to read another bit to calculate the real code + // (this is the "adjusted binary" part) + + if (code >= extras) { + if (!bits) { + if ((read_byte = ((*src)())) == EOF) { +#ifdef KERNEL_MODE + kfree (terminators); kfree (prefixes); kfree (reverse_buffer); +#else + free (terminators); free (prefixes); free (reverse_buffer); +#endif + return 1; + } + + shifter = (long) read_byte; + bits = 8; + } + + code = (code << 1) - extras + (shifter & 1); + shifter >>= 1; + bits--; + } + + if (code == next) // sending the maximum code is reserved for the end of the file + break; + else if (code == CLEAR_CODE) // otherwise check for a CLEAR_CODE to start over early + next = FIRST_STRING; + else if (prefix == CLEAR_CODE) { // this only happens at the first symbol which is always sent + (*dst)(code); // literally and becomes our initial prefix + next++; + } + // Otherwise we have a valid prefix so we step through the string from end to beginning storing the + // bytes in the "reverse_buffer", and then we send them out in the proper order. One corner-case + // we have to handle here is that the string might be the same one that is actually being defined + // now (code == next-1). Also, the first 256 entries of "terminators" and "prefixes" are fixed and + // not allocated, so that messes things up a bit. + else { + int cti = (code == next-1) ? prefix : code; + unsigned char *rbp = reverse_buffer, c; + + do *rbp++ = cti < 256 ? cti : terminators [cti - 256]; // step backward through string... + while ((cti = (cti < 256) ? NULL_CODE : prefixes [cti - 256]) != NULL_CODE); + + c = *--rbp; // the first byte in this string is the terminator for the last string, which is + // the one that we'll create a new dictionary entry for this time + + do (*dst)(*rbp); // send string in corrected order (except for the terminator + while (rbp-- != reverse_buffer); // which we don't know yet) + + if (code == next-1) + (*dst)(c); + + prefixes [next - 1 - 256] = prefix; // now update the next dictionary entry with the new string + terminators [next - 1 - 256] = c; // (but we're always one behind, so it's not the string just sent) + + if (++next == total_codes) // check for full dictionary, which forces a reset (and, BTW, + next = FIRST_STRING; // means we'll never use the dictionary entry we just wrote) + } + + prefix = code; // the code we just received becomes the prefix for the next dictionary string entry + // (which we'll create once we find out the terminator) + } + +#ifdef KERNEL_MODE + kfree (terminators); kfree (prefixes); kfree (reverse_buffer); +#else + free (terminators); free (prefixes); free (reverse_buffer); +#endif + return 0; +} diff --git a/device/gxx-linux/motorboard/motorboard.cpp b/device/gxx-linux/motorboard/motorboard.cpp index 1c6cb0f..48d3258 100644 --- a/device/gxx-linux/motorboard/motorboard.cpp +++ b/device/gxx-linux/motorboard/motorboard.cpp @@ -7,31 +7,48 @@ #include "config.h" #include "StopWatch.h" #include "applog.h" -#include "Capturer.h" +#include "StateControl.h" +#include "Displaydef.h" +#include "MotorConfig.h" +#include "DisplayCenter.h" + static const std::string loggername = "MotorBoard"; -MotorBoard::MotorBoard() +MotorBoard::MotorBoard(std::shared_ptr wake) : devPort(MOTOR_UART), - m_glue({nullptr, nullptr, nullptr,nullptr,nullptr,nullptr}) + m_glue({nullptr, nullptr, nullptr,nullptr,nullptr,nullptr,nullptr}) { LOG_INIT(); - m_uartEnable.reset(new GpioOut(152)); - m_uartEnable->setDirection(Gpio::out); - // m_uartEnable->setEdge(Gpio::rising); + //m_uartEnable.reset(new GpioOut(149)); //m_uartEnable->setValue(Gpio::Low); std::this_thread::sleep_for(std::chrono::milliseconds(10)); m_regsAccess.reset(new UartRegsAccess(devPort, bauds, 0x07, 0x87)); m_intPinMonitor.reset(new PinMonitor(intport, std::bind(&MotorBoard::pin_call, this, std::placeholders::_1))); - //m_scansensorMonitor.reset(new PinMonitor(149, std::bind(&MotorBoard::scansensor_call, this, std::placeholders::_1))); //m_uartEnable->setValue(Gpio::High); std::this_thread::sleep_for(std::chrono::milliseconds(10)); m_os_mode = os_mode(); + m_statecontrol.reset(new StateControl(m_regsAccess,wake)); + m_wake = wake; } + static int paperinnum = 0; -void MotorBoard::start() +void MotorBoard::start(HGScanConfig cfg) { + m_config = cfg; keep_last_paper=false; + paperinnum = 0; + m_paperout_count = 0; + clear_error(); + set_time_error(120); + set_double_inpect(m_config.g200params.double_feed_enbale); + set_staple_inpect(m_config.g200params.stable_enbale); + set_paper_inspect(0); + set_auto_paper(m_config.g200params.is_autopaper,m_config.g200params.en_anlogic_key); + set_screw_inpect(m_config.g200params.screw_detect_enable); + set_screw_level(m_config.g200params.screw_detect_level); + set_long_paper(true); + unsigned int val; SMBCONFIG *smbc = (SMBCONFIG *)(&val); read(0, val); @@ -39,18 +56,29 @@ void MotorBoard::start() write(0, val); smbc->enable = 1; write(0, val); - paperinnum =0 ; + + en_lifter(); } void MotorBoard::stop() { + printf("MotorBoard Stop \n"); unsigned int val; SMBCONFIG *smbc = (SMBCONFIG *)(&val); read(0, val); smbc->enable = 0; write(0, val); } - +bool MotorBoard::en_lifter() +{ + unsigned int val; + SMBCONFIG *smbc = (SMBCONFIG *)(&val); + read(0x00, val); + smbc->lifter_en = 1; + write(0x00, val); + smbc->lifter_en = 0; + return write(0x00, val); +} void MotorBoard::pick_paper(void) { @@ -59,74 +87,14 @@ void MotorBoard::pick_paper(void) read(0x00, val); smbc->pick_paper = 0; write(0x00, val); + std::this_thread::sleep_for(std::chrono::microseconds(500)); smbc->pick_paper = 1; write(0x00, val); // smbc->pick_paper = 0; // write(0x00, val); } -void MotorBoard::clear_error() -{ - unsigned int val; - SMBCONFIG *smbc = (SMBCONFIG *)(&val); - read(0, val); - smbc->error_clean = 1; - write(0, val); - smbc->error_clean = 0; - write(0, val); -} - -bool MotorBoard::wait_paper_in(int timeout_ms) -{ - return cv_paper_in.wait(timeout_ms); -} - -bool MotorBoard::wait_paper_out(int timeout_ms) -{ - return cv_paper_out.wait(timeout_ms); -} - - -int MotorBoard::os_mode() -{ - unsigned int val; - read(0x02, val); - SMB_MODE *smb_mode = (SMB_MODE *)&val; - return smb_mode->scan_mode; -} - -bool MotorBoard::paper_ready() -{ - unsigned int val; - read(0x02, val); - 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; - read(0x02, val); - SMB_MODE *smb_mode = (SMB_MODE *)&val; - return smb_mode->work_status; -} - -bool MotorBoard::is_jam() -{ - return false; -} - -void MotorBoard::motor_reset(){ -} - -void MotorBoard::clean_paper_road() -{ +void MotorBoard::clean_paper_road(){ unsigned int val; SMB_FUNC *smbc = (SMB_FUNC *)(&val); read(6, val); @@ -140,6 +108,83 @@ void MotorBoard::clean_paper_road() else{ printf("\n 非空闲模式不允许清理纸道!!!!"); } + +} + +void MotorBoard::clear_error() +{ + unsigned int val; + SMBCONFIG *smbc = (SMBCONFIG *)(&val); + read(0, val); + smbc->error_clean = 1; + write(0, val); + smbc->error_clean = 0; + write(0, val); +} + +bool MotorBoard::wait_arrival_top(int timeout_ms) +{ + return cv_arrival_top.wait(timeout_ms); +} + +bool MotorBoard::wait_paper_in(int timeout_ms) +{ + return cv_paper_in.wait(timeout_ms); +} + +bool MotorBoard::wait_error(int timeout_ms) +{ + return cv_error.wait(timeout_ms); +} + +bool MotorBoard::wait_paper_out(int timeout_ms) +{ + // StopWatch sw; + // LOG_TRACE("wait_paper_out "); + // while(sw.elapsed_ms() 0) + // { + // m_paperout_count--; + // return true; + // } + // std::this_thread::sleep_for(std::chrono::milliseconds(1)); + // } + // return false; + return cv_paper_out.wait(timeout_ms); +} + +bool MotorBoard::wait_done(int timeout_ms) +{ + return cv_scan_done.wait(timeout_ms); +} + +int MotorBoard::os_mode() +{ + // unsigned int val; + // read(0x02, val); + // SMB_MODE *smb_mode = (SMB_MODE *)&val; + // return smb_mode->scan_mode; + unsigned int val; + read(0x06,val); + SMB_FUNC smb_func = *(SMB_FUNC*)&val; + return smb_func.param.work_mode == 1; +} + +bool MotorBoard::paper_ready() +{ + unsigned int val; + read(0x02, val); + SMB_MODE *smb_mode = (SMB_MODE *)&val; + return smb_mode->feeding_paper_ready; +} + +bool MotorBoard::is_scanning() +{ + unsigned int val; + read(0x02, val); + SMB_MODE *smb_mode = (SMB_MODE *)&val; + return smb_mode->work_status; } int MotorBoard::paper_counter() @@ -150,31 +195,54 @@ 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) { unsigned int val; if (!read(0x00, val)) return false; + enable?m_statecontrol->lcdcontrol(4):m_statecontrol->lcdcontrol(5); SMBCONFIG *smb_config = (SMBCONFIG *)&val; smb_config->double_paper = enable; return write(0x00, val); } - -bool MotorBoard::set_auto_paper(bool enable){ - unsigned int val; - if (!read(0x00, val)) - return false; - SMBCONFIG *smb_config = (SMBCONFIG *)&val; - smb_config->autofeed_mode = enable; - return write(0x00, val); +bool MotorBoard::get_doublle_inpect() +{ + return 0; } - bool MotorBoard::set_staple_inpect(bool enable) { unsigned int val; @@ -184,8 +252,30 @@ bool MotorBoard::set_staple_inpect(bool enable) smb_config->staple_enable = enable; return write(0x00, val); } +bool MotorBoard::get_staple_inpect() +{ + return 0; +} +bool MotorBoard::set_cuospeed(int value) +{ + unsigned int val; + if (!read(0x4, val)) + return false; + SMBCONFIGEXT *smb_config = (SMBCONFIGEXT *)&val; + smb_config->cuo_speed = value; + return write(0x04, val); +} +bool MotorBoard::set_en600DPI(bool en) +{ + unsigned int val; + if (!read(0x00, val)) + return false; + SMBCONFIG *smb_config = (SMBCONFIG *)&val; + smb_config->dpi600 = en?1:0; + return write(0x00, val); +} bool MotorBoard::set_color_mode(int mode) { unsigned int val; @@ -195,8 +285,12 @@ bool MotorBoard::set_color_mode(int mode) smb_config->color_mode = mode; return write(0x00, val); } +int MotorBoard::get_color_mode() +{ + return 0; +} -bool MotorBoard::set_speed_mode(int mode,int dpi,int iscolor) +bool MotorBoard::set_speed_mode(int mode) { unsigned int val; if (!read(0x00, val)) @@ -219,47 +313,34 @@ int MotorBoard::get_speed_mode() return smb_config->v_setting; } -bool MotorBoard::set_cuospeed(unsigned int speed,uint dpi,uint iscolor) -{ - unsigned int val; - if (!read(0x04, val)) - return -1; - SMB_CONFIG_EXT *smb_config = (SMB_CONFIG_EXT *)&val; - smb_config->cuo_speed = speed; - return write(0x04,val); - -} - std::shared_ptr MotorBoard::regs() { return m_regsAccess; } - -static int pinindex=0; +static int countindex =0; void MotorBoard::pin_call(unsigned int pinNum) { static int index = 0; - LOG_TRACE(string_format("pin %d", index++)); - int os_m = os_mode(); - if (m_os_mode != os_m) - { - m_os_mode = os_m; - if (m_glue.m_os_mode_call) - m_glue.m_os_mode_call(m_os_mode); - } + // int os_m = os_mode(); //安路屏蔽计数 扫描过程中无法操作按键 + // 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); + // } - if (m_os_mode) - { - LOG_TRACE("not scan mode"); - return; - } + // if (m_os_mode) //安路屏蔽计数返回 以刷新计数状态 + // { + // LOG_TRACE("not scan mode"); + // return; + // } unsigned int val; SMBSTATUS *smb_status = (SMBSTATUS *)&val; if (!read(0x01, val)) LOG_TRACE("read error"); LOG_TRACE(string_format("status %08x", val)); - //printf("\n reg 1 val =%d",val); if(val & 0x800){ //printf("\n keep_last_paper "); keep_last_paper=true; @@ -279,11 +360,38 @@ void MotorBoard::pin_call(unsigned int pinNum) if(m_glue.m_auto_paper) m_glue.m_auto_paper(1); } - if (val & 0xAFE) + if (val & 0x7c003FE) { + SetKeyState(false); + 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 - + if(val & 0x30efe){ + cv_paper_out.notify_all(); + m_paperout_count++; + } + errormsg(val & 0x1c003fa); + if((val & 0x4) ||(val & 0x02000000)) + { + if(m_glue.m_coveropen_call) + m_glue.m_coveropen_call((val & 0x4));//cover open & 0x04 + if(val & 0x4){ + PutMsg(DisType::Dis_Err_CoverOpen,0,ClearScreen::All); + set_auto_paper(false,false); + autopaperkeystop?autopaperkeystop():void(0); + if(m_statecontrol){ + m_statecontrol->setcoverstate(true); + m_statecontrol->setmenuindex(0); + } + } + else{ + PutMsg(DisType::Dis_Idel,0,ClearScreen::All); + m_statecontrol?m_statecontrol->setcoverstate(false):void(); + } + return; + } + if(smb_status->double_clean_f) + PutMsg(DisType::Dis_Idel,0,ClearScreen::All); LOG_TRACE("error"); return; } @@ -292,48 +400,56 @@ void MotorBoard::pin_call(unsigned int pinNum) if (!smb_status->scan_pulse) { cv_paper_in.notify_all(); - LOG_TRACE("paper in"); - printf("\n paper pulse num = %d ", paperinnum++); + unsigned int papercount = 0; + read(0x02,papercount); + SMBMODE smbmode = *(SMBMODE*)&papercount; + printf("paper in arm count = %d ,motorcount = %d time = %s\n",++countindex,smbmode.scan_num); + startcapimage(true); + PutMsg(DisType::Dis_Scan_Page, smbmode.scan_num,ClearScreen::BOT); } - if(smb_status->paper_left) { cv_paper_out.notify_all(); - LOG_TRACE("paper left"); + m_paperout_count++; + //printf("paper out time = %s \n",GetCurrentTimeStamp(2).c_str()); + startcapimage(true); + LOG_TRACE(string_format("m_paperout_count %s",to_string(m_paperout_count))); } } if (val & 0x400) { LOG_TRACE("done"); + cv_scan_done.notify_all(); if (m_glue.m_scan_done_call) m_glue.m_scan_done_call(); + cv_paper_out.notify_all(); + clear_error(); + SetKeyState(false); + if(m_wake.get()) + m_wake->setsleepfalg(false); } } -void MotorBoard::set_capture(std::shared_ptr cap) -{ - m_cap= cap; -} - -void MotorBoard::scansensor_call(unsigned int pinNum) -{ - // static int indexscansensor=0; - // m_uartEnable->setValue(Gpio::High); - // LOG_TRACE(string_format(" gpio149 call times -%d ", indexscansensor++)); - // cv_paper_in.notify_all(); - // m_uartEnable->setValue(Gpio::Low); -} bool MotorBoard::write(unsigned int addr, unsigned int val) { - return m_regsAccess->write(addr, val); + return m_regsAccess.get()?m_regsAccess->write(addr, val):false; } bool MotorBoard::read(unsigned int addr, unsigned int &val) { - return m_regsAccess->read(addr, val); + return m_regsAccess.get()?m_regsAccess->read(addr, val):false; } + bool MotorBoard::set_time_error(int value){ + unsigned int val; + if (!read(0x05, val)) + return false; + SMBCONFIGTIME *smb_config = (SMBCONFIGTIME *)&val; + smb_config->error_time_set = value; + return write(0x05, val); + } + void MotorBoard::set_callbacks(MotorBoardGlue glue) { m_glue = glue; @@ -366,6 +482,16 @@ bool MotorBoard::set_screw_level(int level) return write(0x00, val); } +bool MotorBoard::set_auto_paper(bool enable,bool enkey){ + unsigned int val; + if (!read(0x00, val)) + return false; + m_statecontrol?m_statecontrol->setautopaperflag(enable,enkey):void(0); + SMBCONFIG *smb_config = (SMBCONFIG *)&val; + smb_config->autofeed_mode = enable; + return write(0x00, val); +} + bool MotorBoard::set_long_paper(bool enable) { unsigned int val; @@ -385,3 +511,180 @@ int MotorBoard::get_screw_level() SMBCONFIG *smb_mode = (SMBCONFIG *)&val; return smb_mode->skew_parameter; } + +void MotorBoard::start_countmode() +{ + unsigned int regval=0; + + read(0x06,regval); + LOG_TRACE(string_format("func6 regval = %08x",regval)); + SMBFUNC func = *(SMBFUNC*)®val; + func.param.work_mode =1; + func.param.func_feed_mid = 1; + func.param.func_clear_count = 1; + LOG_TRACE(string_format("func6 value = %08x",func.value)); + write(0x06,func.value); + func.param.func_encount = 1; + func.param.key_sound = 1; + func.param.func_clear_count = 0; + LOG_TRACE(string_format("func6 value = %08x",func.value)); + write(0x06,func.value); + func.param.func_encount = 0; + func.param.key_sound = 0; + LOG_TRACE(string_format("func6 value = %08x",func.value)); + write(0x06,func.value); +} + + +void MotorBoard::PutMsg(DisType type,int value,ClearScreen clearscreen) +{ + if(m_statecontrol.get()) + m_statecontrol->PutMsg(type,value,clearscreen); +} + +void MotorBoard::errormsg(uint value) +{ + if (value & 0x2) + PutMsg(DisType::Dis_Err_NoPaper,0,ClearScreen::All); + else if (value & 0x8) + PutMsg(DisType::Dis_Err_FeedError,0,ClearScreen::All); + // else if (value & 0x10) + // PutMsg(DisType::Dis_Err_JamIn,0,ClearScreen::All); + else if (value & 0x20) + PutMsg(DisType::Dis_Err_DoubleFeed,0,ClearScreen::All); + else if (value & 0x40) + PutMsg(DisType::Dis_Err_Stable,0,ClearScreen::All); + else if (value & 0x80) + PutMsg(DisType::Dis_Err_PaperScrew,0,ClearScreen::All); + else if (value & 0x00010000) + PutMsg(DisType::Dis_Err_AqrImgTimeout,0,ClearScreen::All); + else if((value & 0x1000010) == 0x1000010) + PutMsg(DisType::Dis_Err_JamIn,3,ClearScreen::All); + else if((value & 0x800010) == 0x800010) + PutMsg(DisType::Dis_Err_JamIn,2,ClearScreen::All); + else if((value & 0x400010) == 0x400010) + PutMsg(DisType::Dis_Err_JamIn,1,ClearScreen::All); +} + +void MotorBoard::SetKeyState(bool value) +{ + if(m_statecontrol) + m_statecontrol->setrunstate(value); +} + + +void MotorBoard::set_keystopenable(bool value){ + unsigned int regval=0; + read(0x06,regval); + LOG_TRACE(string_format("func6 regval = %08x",regval)); + SMBFUNC func = *(SMBFUNC*)®val; + func.param.key_stop_enable = value; + write(0x06,regval); +} + + +void MotorBoard::set_freq(int motor_choose,int speedmode,int colormode,int dpi) +{ + MotorConfig cf; + auto params = cf.GetMotorSpeedParams(motor_choose == 1?0:1,MotorConfig::MTBDType::MT_DRV); + MotorSpeedParam param; + //printf("\n---node.dpi ==%d && node.colormode == %d && node.speed == %d----- ",dpi,colormode,speedmode); + for(auto &node : params) + { + if(node.dpi == dpi && node.colormode == colormode && node.speed == speedmode) + { + param = node.mt_param; + //printf("\n-------------------------------------------------"); + break; + } + } + std::vector table; + if(motor_choose == 0) + { + int x = (dpi == 1?(jsonconfig().getscannerinfo().chu_motor_speed_200):(dpi == 2?jsonconfig().getscannerinfo().chu_motor_speed_300 : jsonconfig().getscannerinfo().chu_motor_speed_600)); + unsigned int regval=0; + read(0x06,regval); + SMBFUNC func = *(SMBFUNC*)®val; + func.param.motor_choose = motor_choose; + func.param.wr_en = 1; + write(0x06,func.value); + write(0x04,x); + //func.param.wr_en = 0; + //write(0x06,func.value); + return ; + } + if(motor_choose == 1) + table = frep_cfg(param.finalPeriod,param.Fmin,param.stepnum,param.a,param.offset,param.finalDelay,param.acceleration_time); + if(motor_choose == 2) + table = frep_cfg(param.finalPeriod,param.Fmin,param.stepnum,param.a,param.offset,param.finalDelay,param.acceleration_time); + if(motor_choose == 3) + table = frep_cfg(param.finalPeriod,param.Fmin,param.stepnum,param.a,param.offset,param.finalDelay,param.acceleration_time); + unsigned int regval=0; + read(0x06,regval); + SMBFUNC func = *(SMBFUNC*)®val; + int start_addr_cuo = 0; +#ifdef G200 + if(motor_choose ==1 && speedmode > 1 && dpi <3) + start_addr_cuo = 63; + if(motor_choose ==1 && dpi ==3) + start_addr_cuo = 127; +#endif + printf("\nstart_addr_cuo =%d ",start_addr_cuo); + for(int i =0;i<256;i++) + { + func.param.motor_choose = motor_choose; + func.param.wr_en = 1; + func.param.motor_addr =i; + write(0x06,func.value); + write(0x04,isetautopaperstopcallback([&]{ + autopaperkeystop?autopaperkeystop():void(0); + if(m_config.g200params.is_autopaper) + set_auto_paper(false,false); + }); + PutMsg(DisType::Dis_Idel,0,ClearScreen::All); +} + +void MotorBoard::release_statecontrol() +{ + autopaperkeystop?autopaperkeystop():void(0); + set_auto_paper(false,false); + m_statecontrol.reset(); + m_regsAccess.reset(); + m_intPinMonitor.reset(); + +} + +void MotorBoard::setautopaperkeystopcallback(std::function func){ + if(func) + autopaperkeystop = func; + m_statecontrol?m_statecontrol->setautopaperstopcallback([&]{ + autopaperkeystop?autopaperkeystop():void(0); + set_auto_paper(false,false); + }):void(0); +} +void MotorBoard::startcapimage(bool value) +{ + // if(m_config.g200params.is_fixedpaper) + // return; + // FILE *fp = fopen("/sys/class/tty/ttyUSB0/device/huagao_scanner", "w"); + // if (fp == NULL) + // perror("startcapimage open filed"); + // else{ + // fprintf(fp, "%d", value ? 1 : 0); + // fclose(fp); + // } +} \ No newline at end of file diff --git a/device/gxx-linux/motorboard/motorboard.h b/device/gxx-linux/motorboard/motorboard.h index 87d0def..ceda2eb 100644 --- a/device/gxx-linux/motorboard/motorboard.h +++ b/device/gxx-linux/motorboard/motorboard.h @@ -1,6 +1,40 @@ #pragma once -#include "Imotorboard.h" +#include +#include +#include +#include +#include "autoevent.hpp" +#include "commondef.h" +#include +#include +#include "wakeup.hpp" +//static std::vector frep_cfg(int a,int b,float k,int s) +static std::vector frep_cfg(int finalPeriod, int Fmin, float stepnum, float a, float offset, float finalDelay,float acceleration_time) +{ + std::vector freq; + int freq_word = 0; + int pulse_word = 0; + for(int i =1;i<=256;i++) + { + freq_word = 8000000/((Fmin+(finalPeriod-Fmin)/(1+exp((-1)*(offset+a*(double)(i)*stepnum))))*2); + pulse_word = ((8000000/acceleration_time)/63)/freq_word; + //printf("\nfreq_word = %d pulse_word = %d",freq_word,pulse_word); + freq.push_back((pulse_word&0xffff)+((freq_word&0xffff)<<16)); + } + return freq; +} +class IRegsAccess; +class PinMonitor; +class Gpio; +class StateControl; +enum class DisType; +enum class ClearScreen; +/* +注: + 安路电机板已去除幅面检测以及休眠配置相关寄存器操作, + 休眠将由Arm 进行控制 +*/ typedef struct SMB_CONFIG { @@ -33,22 +67,27 @@ typedef struct SMB_STATUS unsigned int m1_paper_sin : 1; unsigned int open_machine : 1; unsigned int pick_failed : 1; - unsigned int stop_jam : 1; // 5 + unsigned int stop_jam : 1;//5 unsigned int double_paper : 1; unsigned int staple : 1; unsigned int papertilted : 1; unsigned int count_pulse : 1; - unsigned int scan_mode_change : 1; // 5 + unsigned int scan_mode_change : 1;//5 unsigned int motor_status : 1; unsigned int keep_last_paper : 1; unsigned int sleep_set : 1; - unsigned int sleep_conf : 3; + unsigned int sleep_conf : 3;//6 unsigned int dsp_get_paper_error : 1; unsigned int paper_check_result : 1; - unsigned int arrival_top:1;//������ֽ - unsigned int arrival_top_int:1;//���ﶥ���ж� + unsigned int arrival_top:1;//顶部无纸 + unsigned int arrival_top_int:1;//到达顶部中断 unsigned int auto_feed:1;//4 - unsigned int paper_left:1; + unsigned int paper_left:1; + unsigned int jam_1 : 1; //进纸口 + unsigned int jam_2 : 1; //纸道 + unsigned int jam_3 : 1; //出纸口 + unsigned int cover_closed : 1; //已关盖 + unsigned int double_clean_f : 1; //液晶双张错误清除 } SMBSTATUS; typedef struct SMB_MODE @@ -95,49 +134,64 @@ typedef union SMB_FUNC unsigned int value; } SMBFUNC; -class MotorBoard : public IMotorBoard +class MotorBoard { public: - MotorBoard(); - - 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; + MotorBoard(std::shared_ptr wake); + void start(HGScanConfig cfg); + void stop(); + void clear_error(); + void pick_paper(); + int os_mode(); + bool paper_ready(); + bool is_scanning(); + int paper_counter(); + bool en_lifter(); + bool set_long_paper(bool enable); + bool set_double_inpect(bool enable); + bool get_doublle_inpect(); + bool set_staple_inpect(bool enable); + bool get_staple_inpect(); + bool set_color_mode(int mode); + int get_color_mode(); + int get_speed_mode(); + bool set_auto_paper(bool enable,bool enkey); + 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_arrival_top(int timeout_ms); + bool wait_paper_in(int timeout_ms); + bool wait_paper_out(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); + void set_callbacks(MotorBoardGlue glue); + bool set_cuospeed(int value); + bool get_keeplastpaper(); + bool set_en600DPI(bool en); + bool set_time_error(int value); + void start_countmode(); + std::shared_ptr regs(); + void PutMsg(DisType type,int value,ClearScreen clearscreen); + void SetKeyState(bool value); + void set_freq(int motor_choose,int speedmode,int colormode,int dpi); + void set_keystopenable(bool value); + void init_statecontrol(); + void release_statecontrol(); + void setautopaperkeystopcallback(std::function func); + void errormsg(uint value); + void startcapimage(bool value); + void clean_paper_road(); private: void pin_call(unsigned int pinNum); - void scansensor_call(unsigned int pinNum); + const std::string devPort; const unsigned int bauds = 921600; const int readflag = 0x07; @@ -145,12 +199,18 @@ private: const unsigned int intport = 151; std::shared_ptr m_regsAccess; std::shared_ptr m_intPinMonitor; - std::shared_ptr m_uartEnable; - AutoSemaphore cv_paper_out; + std::shared_ptr m_statecontrol; + std::shared_ptr m_wake; + std::atomic_uint m_paperout_count; AutoSemaphore cv_paper_in; + AutoSemaphore cv_arrival_top; + AutoSemaphore cv_paper_out; + AutoSemaphore cv_error; + AutoSemaphore cv_scan_done; + AutoSemaphore cv_os_mode; + HGScanConfig m_config; unsigned int m_os_mode; volatile bool keep_last_paper; MotorBoardGlue m_glue; - std::shared_ptr m_cap; - bool b_paperin; + std::function autopaperkeystop; }; \ No newline at end of file diff --git a/device/gxx-linux/motorboard/motormanager.cpp b/device/gxx-linux/motorboard/motormanager.cpp deleted file mode 100644 index d46d4f7..0000000 --- a/device/gxx-linux/motorboard/motormanager.cpp +++ /dev/null @@ -1,320 +0,0 @@ -#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 deleted file mode 100644 index 1352e8e..0000000 --- a/device/gxx-linux/motorboard/motormanager.h +++ /dev/null @@ -1,72 +0,0 @@ -#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/opcode.h b/device/gxx-linux/motorboard/opcode.h new file mode 100644 index 0000000..cf0ad91 --- /dev/null +++ b/device/gxx-linux/motorboard/opcode.h @@ -0,0 +1,142 @@ +/******************************************************************* +* Copyright (c) 2011 -2021 Anlogic Inc. + * The Software is distributed in source code form and is open to + * re-distribution and modification where applicable +*******************************************************************/ + + +#ifndef OPCODE_H +#define OPCODE_H + + +#define AJE_DEBUG + + + +// SVF OpCode +#define UNKNOWN 0x00 +#define TRST 0x01 +#define ON 0x02 +#define OFF 0x03 +#define STATE 0x04 +#define ENDIR 0x05 +#define ENDDR 0x06 +#define FREQUENCY 0x07 +#define HZ 0x08 +#define TDR 0x09 +#define TIR 0x0A +#define HDR 0x0B +#define HIR 0x0C +#define SDR 0x0D +#define SIR 0x0E +#define TDI 0x0F +#define TDO 0x10 +#define MASK 0x11 +#define SMASK 0x12 +#define RUNTEST 0x13 +#define TCK 0x14 +#define ENDCMD 0x15 +#define LEFTPAREN 0x16 +#define CONTINUE 0x17 +#define WAIT 0x18 +#define XSDR 0x19 +#define XTDI 0x1A +#define XTDO 0x1B +#define RSDR 0x1C /* It means two SDRs and TDI data of second SDR is the same as TDO of first SDR */ +#define HEADER 0x20 /* Add the specified header to AJE file */ +#define COMMENT 0x21 /* Write comments in SVF file into AJE file */ +#define SETFLOW 0x22 /* Change the flow control register. */ +#define RESETFLOW 0x23 /* Clear the flow control register. */ + +#define LOOP 0x24 +#define ENDLOOP 0x25 + +// Header +#define FILECRC 0x61 +#define MEM 0x62 // The maximum memory needed to allocate in order hold one row of data. +#define ENDFILE 0x7F // End of the file +#define BEGINLINE 0x5E // Begining of line +#define ENDLINE 0x24 // End of line + +// JTAG OpCode +#define RESET 0x00 +#define IDLE 0x01 +#define IRSHIFT 0x02 +#define DRSHIFT 0x03 +#define DRPAUSE 0x04 +#define IRPAUSE 0x05 +#define DRSELECT 0x06 +#define IRSELECT 0x07 +#define DRCAPTURE 0x08 +#define IRCAPTURE 0x09 +#define DREXIT1 0x10 +#define IREXIT1 0x11 +#define DREXIT2 0x12 +#define IREXIT2 0x13 +#define DRUPDATE 0x14 +#define IRUPDATE 0x15 + +// Flow control register bit definitions. +// A set bit indicates that the register currently exhibits the corresponding mode. +#define INTEL_PRGM 0x0001 /* Intelligent programming is in effect. */ +#define CASCADE 0x0002 /* Currently splitting large SDR. */ +#define REPEATLOOP 0x0008 /* Currently executing a repeat loop. */ +#define SHIFTRIGHT 0x0080 /* The next data stream needs a right shift. */ +#define SHIFTLEFT 0x0100 /* The next data stream needs a left shift. */ +#define VERIFYUES 0x0200 /* Continue if fail is in effect. */ + + +// Vendor Code +#define VENDOR 0x56 +#define ANLOGIC 0x01 +#define XILINX 0x02 +#define ALTERA 0x03 +#define LATTICE 0x04 + +// Mode Code +#define COMP_MODE 0xF1 // compress mode +#define FULL_MODE 0xF2 // full mode + +// SIR Command +#define BYPASS 0xFF +#define SAMPLE 0x05 +#define IDCODE_PUB 0x06 +#define IDCODE_PUB_2 0xE0 + +// Reading IO Status +#define LINE_MAX_SIZE 1000 /* max size of a line when reading svf file */ +#define DATA_MAX_SIZE 300 /* max size of tdi/tdo/mask hex str in svf file */ + +// return type +#define AJE_OK 0 +#define AJE_WARNING -1 +#define AJE_ERROR -2 +#define AJE_FILE_OPEN_FAIL -6 +#define AJE_FILE_INVALID -7 +#define AJE_INVALID_COMMAND -10 +#define AJE_INVALID_VALUE -11 +#define AJE_INVALID_TAP_STATE -12 +#define AJE_TRANSFER_FAIL -16 +#define AJE_VERIFY_FAIL -17 + +/* TAP STATE Enumerate */ +enum TAP_STATE { + TAP_RESET = 0, /* Initialization state */ + TAP_IDLE = 1, + TAP_DRSELECT = 2, /* DR STATE: 2~8 */ + TAP_DRCAPTURE = 3, + TAP_DRSHIFT = 4, + TAP_DREXIT1 = 5, + TAP_DRPAUSE = 6, + TAP_DREXIT2 = 7, + TAP_DRUPDATE = 8, + TAP_IRSELECT = 9, /* IR STATE: 9~15 */ + TAP_IRCAPTURE = 10, + TAP_IRSHIFT = 11, + TAP_IREXIT1 = 12, + TAP_IRPAUSE = 13, + TAP_IREXIT2 = 14, + TAP_IRUPDATE = 15, +}; + +#endif // OPCODE_H diff --git a/device/gxx-linux/motorboard/sensormonitor.cpp b/device/gxx-linux/motorboard/sensormonitor.cpp deleted file mode 100644 index 09d9ac1..0000000 --- a/device/gxx-linux/motorboard/sensormonitor.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#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 deleted file mode 100644 index ee9e924..0000000 --- a/device/gxx-linux/motorboard/sensormonitor.h +++ /dev/null @@ -1,29 +0,0 @@ -#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/vec.cpp b/device/gxx-linux/motorboard/vec.cpp new file mode 100644 index 0000000..9562a47 --- /dev/null +++ b/device/gxx-linux/motorboard/vec.cpp @@ -0,0 +1,521 @@ +/******************************************************************* + * Copyright (c) 2011 -2021 Anlogic Inc. + * This file is strictly confidential. All rights reserved. +*******************************************************************/ + +/*********************************************************************** +Filename: vec.c +Description: generate vec +Log: initial version, July 2019 + ***********************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#include +#include "Jtag.h" + +#include "opcode.h" + + +/* global variables about hdr/hir/tdr/tir */ +unsigned int g_hdr_size = 0; +unsigned int g_hir_size = 0; +unsigned int g_tdr_size = 0; +unsigned int g_tir_size = 0; + +unsigned char* g_hdr_data = NULL; +unsigned char* g_hir_data = NULL; +unsigned char* g_tdr_data = NULL; +unsigned char* g_tir_data = NULL; + +static Jtag jtag_burning; + +/* function declared in ajeutil.c */ +extern int Anlogic_GetBit(unsigned char* data, int id); +extern void Anlogic_SetBit(unsigned char* data, int id, int val); +extern unsigned char Anlogic_ReverseChar(unsigned char byte); + + +/* Function forward declaration */ +void Anlogic_WritePulseTck(void); + +/* Tap Opcode To TAP_STATE */ +enum TAP_STATE Anlogic_TapState(unsigned char opcode) { + enum TAP_STATE state = TAP_RESET; + switch (opcode) { + case RESET: state = TAP_RESET; break; + case IDLE: state = TAP_IDLE; break; + case DRSELECT: state = TAP_DRSELECT; break; + case DRCAPTURE: state = TAP_DRCAPTURE; break; + case DRSHIFT: state = TAP_DRSHIFT; break; + case DREXIT1: state = TAP_DREXIT1; break; + case DRPAUSE: state = TAP_DRPAUSE; break; + case DREXIT2: state = TAP_DREXIT2; break; + case DRUPDATE: state = TAP_DRUPDATE; break; + case IRSELECT: state = TAP_IRSELECT; break; + case IRCAPTURE: state = TAP_IRCAPTURE; break; + case IRSHIFT: state = TAP_IRSHIFT; break; + case IREXIT1: state = TAP_IREXIT1; break; + case IRPAUSE: state = TAP_IRPAUSE; break; + case IREXIT2: state = TAP_IREXIT2; break; + case IRUPDATE: state = TAP_IRUPDATE; break; + default: + printf("Error: Illegal tap state opcode %u\n", (unsigned int)opcode); + } + return state; +} + +/* TAP_STATE to TapState String */ +const char* Anlogic_TapState2Str(enum TAP_STATE tap_state) { +#define X(_w) if (tap_state == TAP_ ## _w) return #_w + X(RESET); + X(IDLE); + X(DRSELECT); + X(DRCAPTURE); + X(DRSHIFT); + X(DREXIT1); + X(DRPAUSE); + X(DREXIT2); + X(DRUPDATE); + X(IRSELECT); + X(IRCAPTURE); + X(IRSHIFT); + X(IREXIT1); + X(IRPAUSE); + X(IREXIT2); + X(IRUPDATE); +#undef X + return "TapState2Str: unkown state"; +} + +static enum TAP_STATE cur_tap_state = TAP_RESET; /* current tap state */ +static enum TAP_STATE end_dr_state = TAP_IDLE; /* the tap state that device goes after sdr */ +static enum TAP_STATE end_ir_state = TAP_IDLE; /* the tap state that device goes after sir */ + + +/* Tap State Transistions */ +int Anlogic_TapTransist(enum TAP_STATE state) { + int id = 0; + int count = 0; + +// printf("Anlogic_TapTransist start...\n"); + if (cur_tap_state == state && state == TAP_RESET) { + for (id = 0; id < 6; ++id) { + jtag_burning.TMS_Wr(1); + + Anlogic_WritePulseTck(); + } +// printf("Anlogic_TapTransist 107 end...\n"); + return 0; + } + + while (cur_tap_state != state) { + switch (cur_tap_state) { + case TAP_RESET: + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_IDLE; + break; + case TAP_IDLE: + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_DRSELECT; + break; + /* DR STATE Transistion */ + case TAP_DRSELECT: + if (state >= TAP_IRSELECT || state == TAP_RESET) { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_IRSELECT; + } else { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_DRCAPTURE; + } + break; + case TAP_DRCAPTURE: + if (state == TAP_DRSHIFT) { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_DRSHIFT; + } else { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_DREXIT1; + } + break; + case TAP_DRSHIFT: + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_DREXIT1; + break; + case TAP_DREXIT1: + if (state == TAP_DRPAUSE) { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_DRPAUSE; + } else { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_DRUPDATE; + } + break; + case TAP_DRPAUSE: + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_DREXIT2; + break; + case TAP_DREXIT2: + if (state == TAP_DRSHIFT) { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_DRSHIFT; + } else { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_DRUPDATE; + } + break; + case TAP_DRUPDATE: + if (state == TAP_IDLE) { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_IDLE; + } else { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_DRSELECT; + } + break; + /* IR STATE Transistion */ + case TAP_IRSELECT: + if (state == TAP_RESET) { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_RESET; + } else { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_IRCAPTURE; + } + break; + case TAP_IRCAPTURE: + if (state == TAP_IRSHIFT) { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_IRSHIFT; + } else { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_IREXIT1; + } + break; + case TAP_IRSHIFT: + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_IREXIT1; + break; + case TAP_IREXIT1: + if (state == TAP_IRPAUSE) { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_IRPAUSE; + } else { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_IRUPDATE; + } + break; + case TAP_IRPAUSE: + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_IREXIT2; + break; + case TAP_IREXIT2: + if (state == TAP_IRSHIFT) { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_IRSHIFT; + } else { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_IRUPDATE; + } + break; + case TAP_IRUPDATE: + if (state == TAP_IDLE) { + jtag_burning.TMS_Wr(0); + cur_tap_state = TAP_IDLE; + } else { + jtag_burning.TMS_Wr(1); + cur_tap_state = TAP_IRSELECT; + } + break; + default: + printf("Error: invalid tap sate.\n"); + return -1; + } + Anlogic_WritePulseTck(); + + if (++count > 10) { + printf("Error: Loop in Tap Transistion."); + return -1; + } + } + jtag_burning.TDI_Wr(0); +// printf("Anlogic_TapTransist 240 end...\n"); + return 0; +} + +/* Init function, set current tap state to reset */ +void Anlogic_Init(void) { + cur_tap_state = TAP_RESET; + Anlogic_TapTransist(TAP_RESET); +} + +/* set the tap state that deevice goes after sdr */ +void Anlogic_SetEndDRState(enum TAP_STATE end_st) { + end_dr_state = end_st; +#ifdef AJE_DEBUG + printf("ENDDR %s;\n", Anlogic_TapState2Str(end_st)); +#endif +} + +/* set the tap state that deevice goes after sir */ +void Anlogic_SetEndIRState(enum TAP_STATE end_st) { + end_ir_state = end_st; +#ifdef AJE_DEBUG + printf("ENDIR %s;\n", Anlogic_TapState2Str(end_st)); +#endif +} + +/* Send HIR/HDR/TIR/TDR data to device */ +void Anlogic_SendBypassData(unsigned int op_code) { + unsigned char* data = NULL; + unsigned int size = 0; + unsigned int index = 0; + unsigned int bit = 0; + + switch (op_code) { + case HIR: size = g_hir_size; data = g_hir_data; break; + case HDR: size = g_hdr_size; data = g_hdr_data; break; + case TIR: size = g_tir_size; data = g_tir_data; break; + case TDR: size = g_tdr_size; data = g_tdr_data; break; + default: break; + } + + /* no value set, use default */ + if (data == NULL) { + bit = (op_code == HIR || op_code == TIR) ? 1 : 0; + } + + for (index = 0; index < size-1; ++index) { + if (data != NULL) { + bit = Anlogic_GetBit(data, index); + } + jtag_burning.TDI_Wr(bit); + Anlogic_WritePulseTck(); + } + + bit = Anlogic_GetBit(data, index); + jtag_burning.TDI_Wr(bit); +} + +/* Send TDI data to device */ +int Anlogic_SendData(unsigned char* tdi_data, unsigned int bin_size, int cascade) { + unsigned int index = 0; + unsigned int bit = 0; + + for (index = 0; index < bin_size-1; ++index) { + bit = Anlogic_GetBit(tdi_data, index); + jtag_burning.TDI_Wr(bit); + Anlogic_WritePulseTck(); + } + + bit = Anlogic_GetBit(tdi_data, index); + jtag_burning.TDI_Wr(bit); + + if (cascade == 1) { + Anlogic_WritePulseTck(); + } + return 0; +} + +/* Send TDI data and read TDO, Verify */ +int Anlogic_ReadData(unsigned char* tdi_data, unsigned char* tdo_data, unsigned char* mask, unsigned int data_size, int cascade) { + unsigned int index = 0; + int tdi_bit = 0; + int tdo_bit = 0; + int mask_bit = 0; + + for (index = 0; index < data_size-1; ++index) { + tdi_bit = Anlogic_GetBit(tdi_data, index); + tdo_bit = Anlogic_GetBit(tdo_data, index); + mask_bit = Anlogic_GetBit(mask, index); + + if (mask_bit == 1 && tdo_bit != jtag_burning.TDO_RD()) { + return AJE_VERIFY_FAIL; + } + + jtag_burning.TDI_Wr(tdi_bit); + Anlogic_WritePulseTck(); + } + + tdi_bit = Anlogic_GetBit(tdi_data, index); + tdo_bit = Anlogic_GetBit(tdo_data, index); + mask_bit = Anlogic_GetBit(mask, index); + + if (mask_bit == 1 && tdo_bit != jtag_burning.TDO_RD()) { + return AJE_VERIFY_FAIL; + } + jtag_burning.TDI_Wr(tdi_bit); + + if (cascade == 1) { + Anlogic_WritePulseTck(); + } + + return AJE_OK; +} + +/* Send TDI Data and Save TDO */ +int Anlogic_SaveData(unsigned char* tdi_data, unsigned int data_size, unsigned char** tdo_data) { + unsigned int index = 0; + unsigned int tdi_bit = 0; + unsigned int tdo_bit = 0; + + for (index = 0; index < data_size-1; ++index) { + tdo_bit = jtag_burning.TDO_RD(); + Anlogic_SetBit(*tdo_data, index, tdo_bit); + tdi_bit = Anlogic_GetBit(tdi_data, index); + jtag_burning.TDI_Wr(tdi_bit); + Anlogic_WritePulseTck(); + } + tdo_bit = jtag_burning.TDO_RD(); + Anlogic_SetBit(*tdo_data, index, tdo_bit); + tdi_bit = Anlogic_GetBit(tdi_data, index); + jtag_burning.TDI_Wr(tdi_bit); + + return AJE_OK; +} + +/* Process SIR/SDR */ +int Anlogic_ProcessShiftCmd(unsigned int op_code, unsigned int cascade, unsigned int read, unsigned int data_size, + unsigned char* tdi_data, unsigned char* tdo_data, unsigned char* mask) { + int rtn_val = AJE_OK; + // process header data + switch (op_code) { + case SIR: + if (cascade != 1) { + Anlogic_TapTransist(TAP_IRSHIFT); + if (g_hir_size > 0) { + Anlogic_SendBypassData(HIR); + Anlogic_WritePulseTck(); + } + } + break; + case SDR: + if (cascade != 1) { + Anlogic_TapTransist(TAP_DRSHIFT); + if (g_hdr_size > 0) { + Anlogic_SendBypassData(HDR); + Anlogic_WritePulseTck(); + } + } + break; + default: + break; + } + + if (read == 1) { + rtn_val =Anlogic_SaveData(tdi_data, data_size, &tdo_data); + } else if (mask == NULL) { + rtn_val =Anlogic_SendData(tdi_data, data_size, cascade); + } else { + rtn_val =Anlogic_ReadData(tdi_data, tdo_data, mask, data_size, cascade); + } + + // process tailer data + switch (op_code) { + case SIR: + if (cascade != 1) { + if (g_tir_size > 0) { + Anlogic_WritePulseTck(); + Anlogic_SendBypassData(TIR); + } + Anlogic_TapTransist(end_ir_state); + } + break; + case SDR: + if (cascade != 1) { + if (g_tdr_size > 0) { + Anlogic_WritePulseTck(); + Anlogic_SendBypassData(TDR); + } + Anlogic_TapTransist(end_dr_state); + } + break; + default: + break; + } + + return rtn_val; +} + +/* process single sir command, do not use bypass data (hir/tir) */ +int Anlogic_ExeSirCommand(unsigned char command, int cur_lvl, int total_lvl) { + int rtn_val = AJE_OK; + unsigned char* tdi_data = NULL; + int id = 0; + Anlogic_TapTransist(TAP_IRSHIFT); + + tdi_data = (unsigned char*)calloc((total_lvl*8+1), sizeof(unsigned char)); + for(id = 0; id < total_lvl; ++id) { + if (id == (total_lvl - cur_lvl)) { + tdi_data[id] = Anlogic_ReverseChar(command); + } else { + tdi_data[id] = 0xFF; + } + } + rtn_val = Anlogic_SendData(tdi_data, total_lvl*8, 0 /*cascade*/); + Anlogic_TapTransist(end_ir_state); + + return rtn_val; +} + +/* process sdr command, do not use bypass data (hdr/tdr) */ +int Anlogic_ExeSdrCommand(unsigned int bit_size, int cur_lvl, int total_lvl, + unsigned char* tdi_data, unsigned char* tdo_data) { + int rtn_val = AJE_OK; + int head_num = total_lvl - cur_lvl; + int tailer_num = cur_lvl-1; + int id = 0; + unsigned int byte_size = (bit_size + 7)/8; + + Anlogic_TapTransist(TAP_DRSHIFT); + if (head_num > 0) { + for (id = 0; id < head_num; ++id) { + jtag_burning.TDI_Wr(0); + Anlogic_WritePulseTck(); + } + } + + if (tdi_data == NULL) { + tdi_data = (unsigned char*)calloc((byte_size+1), sizeof(unsigned char)); + } + + if (tdo_data == NULL) { + rtn_val = Anlogic_SendData(tdi_data, bit_size, 0 /*cascade*/); + } else { /* read and save tdo readback data */ + rtn_val = Anlogic_SaveData(tdi_data, bit_size, &tdo_data /*cascade*/); + } + + if (tailer_num > 0) { + for (id = 0; id < tailer_num; ++id) { + Anlogic_WritePulseTck(); + jtag_burning.TDI_Wr(0); + } + } + + Anlogic_TapTransist(end_dr_state); + return rtn_val; +} + +/* process runtest num tck */ +void Anlogic_ProcessRunTestTck(int num) { + volatile int i = 0; + jtag_burning.TDI_Wr(0); + jtag_burning.TMS_Wr(0); + for(i = 0; i < num; ++i) { + jtag_burning.TCK_Wr(1); + jtag_burning.TCK_Wr(0); + } +#ifdef AJE_DEBUG + printf("RUNTEST %d TCK;\n", num); +#endif +} + +void Anlogic_WritePulseTck(void) { + static unsigned int i = 0; + jtag_burning.TCK_Wr(1); + jtag_burning.TCK_Wr(0); +} diff --git a/device/gxx-linux/motorboard/xmake.lua b/device/gxx-linux/motorboard/xmake.lua index 6cca12f..141c006 100644 --- a/device/gxx-linux/motorboard/xmake.lua +++ b/device/gxx-linux/motorboard/xmake.lua @@ -4,6 +4,7 @@ target("motorboard") set_kind("static") add_syslinks("pthread") add_files("*.cpp") - add_deps("regs", "motor_run" ,"deviceio", "conf", "applog", "capimage",{public = true}) + add_deps("regs", "deviceio","motorcontroller","keymonitor" ,"conf", "applog", {public = true}) add_includedirs(".", { public = true}) + add_includedirs("../scanner",{public = true}) add_packages("common") \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/IState.h b/device/gxx-linux/motorcontroller/IState.h new file mode 100644 index 0000000..27ee558 --- /dev/null +++ b/device/gxx-linux/motorcontroller/IState.h @@ -0,0 +1,32 @@ +#pragma once +#include +#include +#include +#include +#include +#include "Statedef.h" +#include "BlockingQueue.h" +#include "LCDDisplay.h" + +class IState +{ +public: + IState(/* args */){ + display = std::make_unique(); + } + virtual ~IState(){} + virtual void InitState(int state=0) =0; + virtual IState* OnState(StateInfo state) = 0; + virtual void SetBtnCall(std::function call) = 0; + std::string typeName = "FsmState"; + static void SetConfirmCall(std::function confirmcall) + { + m_confirmcall = confirmcall; + } +private: + static std::function m_confirmcall; +protected: + std::unique_ptr display; +}; + + diff --git a/device/gxx-linux/motorcontroller/Menu.cpp b/device/gxx-linux/motorcontroller/Menu.cpp new file mode 100644 index 0000000..92ad7a0 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Menu.cpp @@ -0,0 +1,51 @@ +#include "Menu.h" + +Menu::Menu(const char *const name,DisType dt) : name_(name) +{ + +} + +Menu::~Menu() +{ + std::cout << "Menu " << name_ << " destroyed" << std::endl; + for (auto &item : menu_items) + { + item.reset(); + } +} + +string Menu::get_name() +{ + return name_; +} + +int Menu::select() +{ + int ret = -1; + int choice; + int count = 0; + + for (auto &item : menu_items) + { + std::cout << item->get_name() << " : " << count++ << std::endl; + } + + if (choice >= 0 && choice <= menu_items.size()) + { + ret = menu_items[choice]->select(); + // if(!ret) + // g_call(); + } + + + count = 0; + choice = 0; + + return ret; +} + +void Menu::add_menu_item(unique_ptr menu_item) +{ + menu_items.push_back(std::move(menu_item)); +} + diff --git a/device/gxx-linux/motorcontroller/Menu.h b/device/gxx-linux/motorcontroller/Menu.h new file mode 100644 index 0000000..4e05781 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Menu.h @@ -0,0 +1,16 @@ +#pragma once +#include "Selectable.h" + +class Menu : public Selectable +{ +private: + std::string name_; + vector> menu_items; + +public: + Menu(const char *const name,DisType dt); + virtual ~Menu(); + virtual string get_name() override; + virtual int select() override; + void add_menu_item(unique_ptr menu_item); +}; \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/MenuComponent.cpp b/device/gxx-linux/motorcontroller/MenuComponent.cpp new file mode 100644 index 0000000..694e9fd --- /dev/null +++ b/device/gxx-linux/motorcontroller/MenuComponent.cpp @@ -0,0 +1,135 @@ +#include "MenuComponent.h" +#include "Menu.h" +#include "Menu_Item.h" +#include "commondef.h" + +MenuComponent::MenuComponent() +{ + if (!m_menu.get()) + m_menu.reset(new Menu("Menu",DisType::Dis_Idel)); + current_distype = DisType::Dis_Idel; + cur_index = 0; +} + +MenuComponent::~MenuComponent() +{ + + if (m_menu.get()) + m_menu.reset(); +} + +void MenuComponent::initmenu() +{ + m_keytable.push_back({0,0,1,DisType::Dis_Idel}); //0 + m_keytable.push_back({6,2,0,DisType::Dis_Set_ClearPaperPass}); //1 + m_keytable.push_back({1,3,7,DisType::Dis_Set_PollPaperIntensity}); //2 +#ifdef G200 + m_keytable.push_back({2,4,11,DisType::Dis_Set_SleepMode}); //3 + m_keytable.push_back({3,5,20,DisType::Dis_Set_TrayPosition}); //4 + m_keytable.push_back({4,6,0,DisType::Dis_Set_Poweroff}); //5 +#else + m_keytable.push_back({2,5,11,DisType::Dis_Set_SleepMode}); //3 + m_keytable.push_back({3,5,20,DisType::Dis_Set_TrayPosition}); //4 + m_keytable.push_back({3,6,0,DisType::Dis_Set_Poweroff}); //5 +#endif + m_keytable.push_back({5,1,0,DisType::Dis_Set_Return});//6 + m_keytable.push_back({10,8,2,DisType::Dis_Set_PollPI_High}); //7 + m_keytable.push_back({7,9,2,DisType::Dis_Set_PollPI_Mid}); //8 + m_keytable.push_back({8,10,2,DisType::Dis_Set_PollPI_Low}); //9 + m_keytable.push_back({9,7,2,DisType::Dis_Set_Item_Return}); //10 + m_keytable.push_back({19,12,3,DisType::Dis_Set_SleepMode_5M}); //11 + m_keytable.push_back({11,13,3,DisType::Dis_Set_SleepMode_10M}); //12 + m_keytable.push_back({12,14,3,DisType::Dis_Set_SleepMode_20M}); //13 + m_keytable.push_back({13,15,3,DisType::Dis_Set_SleepMode_30M}); //14 + m_keytable.push_back({14,16,3,DisType::Dis_Set_SleepMode_1H}); //15 + m_keytable.push_back({15,17,3,DisType::Dis_Set_SleepMode_2H}); //16 + m_keytable.push_back({16,18,3,DisType::Dis_Set_SleepMode_4H}); //17 + m_keytable.push_back({17,19,3,DisType::Dis_Set_SleepMode_NEVER}); //18 + m_keytable.push_back({18,11,3,DisType::Dis_Set_Item_Return});//19 + m_keytable.push_back({23,21,4,DisType::Dis_Set_TrayPosition_High}); //20 + m_keytable.push_back({20,22,4,DisType::Dis_Set_TrayPosition_Mid}); //21 + m_keytable.push_back({21,23,4,DisType::Dis_Set_TrayPosition_Low});//22 + m_keytable.push_back({22,20,4,DisType::Dis_Set_Item_Return});//23 + // if (m_menu.get()) + // { + + // unique_ptr menu_clearpass = std::make_unique("clearpass",DisType::Dis_Set_ClearPaperPass); + // m_menu->add_menu_item(std::move(menu_clearpass)); + + // unique_ptr submenu_feedstrength = std::make_unique("feedstrenth",DisType::Dis_Set_PollPaperIntensity); + // std::unique_ptr feeditemH = std::make_unique("feedhigh",DisType::Dis_Set_PollPI_High); + // std::unique_ptr feeditemM = std::make_unique("feedmid",DisType::Dis_Set_PollPI_Mid); + // std::unique_ptr feeditemL = std::make_unique("feedlow",DisType::Dis_Set_PollPI_Low); + // submenu_feedstrength->add_menu_item(std::move(feeditemH)); + // submenu_feedstrength->add_menu_item(std::move(feeditemM)); + // submenu_feedstrength->add_menu_item(std::move(feeditemL)); + // m_menu->add_menu_item(std::move(submenu_feedstrength)); + + // unique_ptr submenu_sleep = std::make_unique("sleepset",DisType::Dis_Set_SleepMode); + // std::unique_ptr sleep30 = std::make_unique("30min",DisType::Dis_Set_SleepMode_30M); + // std::unique_ptr sleep60 = std::make_unique("60min",DisType::Dis_Set_SleepMode_1H); + // std::unique_ptr sleep120 = std::make_unique("120min",DisType::Dis_Set_SleepMode_2H); + // std::unique_ptr sleepnever = std::make_unique("never",DisType::Dis_Set_SleepMode_NEVER); + // submenu_sleep->add_menu_item(std::move(sleep30)); + // submenu_sleep->add_menu_item(std::move(sleep60)); + // submenu_sleep->add_menu_item(std::move(sleep120)); + // submenu_sleep->add_menu_item(std::move(sleepnever)); + // m_menu->add_menu_item(std::move(submenu_sleep)); + + // unique_ptr submenu_poweroff = std::make_unique("poweroff",DisType::Dis_Set_Poweroff); + // m_menu->add_menu_item(std::move(submenu_poweroff)); + // } +} + +void MenuComponent::select() +{ + if (m_menu.get()) + { + m_menu->select(); + } +} + +void MenuComponent::option(int key) +{ + switch (key) + { +#ifdef G200 + case 85: //Key_Menu + cur_index = m_keytable[cur_index].enter; + break; + case 86: //Key_Left + cur_index = m_keytable[cur_index].up; + break; + case 76: //Key_Right + cur_index = m_keytable[cur_index].down; + break; +#else + case 76: //Key_Menu + cur_index = m_keytable[cur_index].enter; + break; + case 77: //Key_Right + cur_index = m_keytable[cur_index].down; + break; +#endif + default: + break; + } +} + +DisType MenuComponent::getcurtype() +{ + return m_keytable[cur_index].m_type; +} + +void MenuComponent::setcurindex(int x) +{ + if(x < 0 || x >= m_keytable.size()) + return ; + cur_index = x; + printf("\n MenuComponent setcurindex %d",x); +} + +int MenuComponent::getcurindex() +{ + return cur_index; +} \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/MenuComponent.h b/device/gxx-linux/motorcontroller/MenuComponent.h new file mode 100644 index 0000000..606d702 --- /dev/null +++ b/device/gxx-linux/motorcontroller/MenuComponent.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include "Displaydef.h" +class Menu; +class Menu_Item; + +struct keypause{ + int up; + int down; + int enter; + DisType m_type; +}; + +class MenuComponent +{ +private: + /* data */ +public: + MenuComponent(/* args */); + ~MenuComponent(); + void initmenu(); + void select(); + void option(int key); + DisType getcurtype(); + void setcurindex(int x); + int getcurindex(); +private: + + std::shared_ptr m_menu; + DisType current_distype; + std::vector m_keytable; + int cur_index; +}; diff --git a/device/gxx-linux/motorcontroller/Menu_Item.cpp b/device/gxx-linux/motorcontroller/Menu_Item.cpp new file mode 100644 index 0000000..0818e0a --- /dev/null +++ b/device/gxx-linux/motorcontroller/Menu_Item.cpp @@ -0,0 +1,24 @@ +#include "Menu_Item.h" + +Menu_Item::Menu_Item(const char *const name,DisType dt) : name_{name} +{ + +} + +Menu_Item::~Menu_Item() +{ + std::cout<<"Menu_Item Name "<(&MotorController::runloop,this); + auto keycall=[&](int key) + { + auto iter = m_keystats.find((HgBtn)key); + if(iter!=m_keystats.end()) + { + m_msg.Put(iter->second); + } + }; + m_keyMinitor= make_shared(keycall); +} + +MotorController::~MotorController() +{ + + if(m_threadmsgloop.get() && m_threadmsgloop->joinable()) + { + m_bloop = false; + m_threadmsgloop->join(); + m_threadmsgloop.reset(); + } + LOG_TRACE("MotorController ~ctor exit \n"); +} + +void MotorController::runloop() +{ + m_bloop = true; + IState* mtstate = StateManager::GetState(); + m_msg.Put({HGScannerStatus::Mode_Idel,0}); + while (m_bloop) + { + auto msg = m_msg.Take(); + printf("\n msg status = %d ",msg.status); + if(msg.status == HGScannerStatus::Mode_Scan_Start) + mtstate = StateManager::GetState(); + if(msg.status == HGScannerStatus::Mode_Count) + mtstate = StateManager::GetState(msg.value); + if(msg.status == HGScannerStatus::Mode_Set_Key_Manual) + mtstate = StateManager::GetState(); + if(msg.status >= HGScannerStatus::Mode_Error_Jam && msg.status <= HGScannerStatus::Mode_Error_DogEar || msg.status == HGScannerStatus::Mode_Error_FeedError) + mtstate = StateManager::GetState((int)msg.status); + if(msg.status == HGScannerStatus::Mode_Idel) + mtstate = StateManager::GetState(); + //mtstate = mtstate->OnState(msg); + } +} + +void MotorController::PutMsg(StateInfo mode) +{ + m_msg.Put(mode); +} + + +void MotorController::SendMsg() +{ + +} + + diff --git a/device/gxx-linux/motorcontroller/MotorController.h b/device/gxx-linux/motorcontroller/MotorController.h new file mode 100644 index 0000000..48b6864 --- /dev/null +++ b/device/gxx-linux/motorcontroller/MotorController.h @@ -0,0 +1,36 @@ +#pragma once +#include "StateManager.h" +#include "IState.h" +#include "BlockingQueue.h" +#include "keymonitor.h" + +using HgBtn = KeyMonitor::HGKey; + +class MotorController +{ +public: + MotorController(/* args */); + ~MotorController(); + void PutMsg(StateInfo mode); +private: + void runloop(); + void SendMsg(); + void procmsg(); + +private: + std::atomic m_bloop; + BlockingQueue m_msg; + std::shared_ptr m_threadmsgloop; + std::shared_ptr m_keyMinitor; + const std::map m_keystats={ + {HgBtn::Key_Enter,{HGScannerStatus::Mode_Set_Key_Enter,0}}, + {HgBtn::Key_Cancle,{HGScannerStatus::Mode_Set_Key_Back,0}}, + {HgBtn::Key_Count,{HGScannerStatus::Mode_Set_Key_Count,0}}, + {HgBtn::Key_Handle,{HGScannerStatus::Mode_Set_HandMode,0}}, + {HgBtn::Key_DoubleFeed,{HGScannerStatus::Mode_Set_Key_EnDoubleFeed,0}}, + {HgBtn::Key_Left,{HGScannerStatus::Mode_Set_Key_Left,0}}, + {HgBtn::Key_Menu,{HGScannerStatus::Mode_Set_Key_Manual,0}}, + {HgBtn::Key_Right,{HGScannerStatus::Mode_Set_Key_Right,0}}, + {HgBtn::Key_Clear,{HGScannerStatus::Mode_Set_Key_ClearCount,0}} + }; +}; diff --git a/device/gxx-linux/motorcontroller/MotorboardParam.cpp b/device/gxx-linux/motorcontroller/MotorboardParam.cpp new file mode 100644 index 0000000..40337f4 --- /dev/null +++ b/device/gxx-linux/motorcontroller/MotorboardParam.cpp @@ -0,0 +1,176 @@ +#include "MotorboardParam.h" +#include +#include +#include +#include "commondef.h" +#include +MotorboardParam::MotorboardParam(/* args */) +{ +} + +MotorboardParam::~MotorboardParam() +{ +} + +int MotorboardParam::GetOrSetEnableAutomaticControlFeedMode(bool isget,int value){ + std::lock_guard lc(m_setlock); + if(isget) + { + auto js = getjson(); + if(!js[automaticcontrol_feedmode].is_null() && js[automaticcontrol_feedmode].is_number()) + return js[automaticcontrol_feedmode]; + else{ + printf("\nread motorboardparam error : feedmode!!! "); + return 1; + } + } + else{ + auto js = getjson(); + if(!js[automaticcontrol_feedmode].is_null() && js[automaticcontrol_feedmode].is_number()) + { + js[automaticcontrol_feedmode] = value; + savejson(js); + } + return 0; + } +} + +int MotorboardParam::GetOrSetFeedMode(bool isget,int value){ + std::lock_guard lc(m_setlock); + if(isget) + { + auto js = getjson(); + if(!js[feed_mode].is_null() && js[feed_mode].is_number()) + return js[feed_mode]; + else{ + printf("\nread motorboardparam error : feedmode!!! "); + return 1; + } + } + else{ + if(value < 0 || value > 2) + return 0; + auto js = getjson(); + if(!js[feed_mode].is_null() && js[feed_mode].is_number()) + { + js[feed_mode] = value; + savejson(js); + } + return 0; + } +} + +int MotorboardParam::GetOrSetTrayPosition(bool isget,int value){ + std::lock_guard lc(m_setlock); + if(isget) + { + auto js = getjson(); + if(!js[trayposition].is_null() && js[trayposition].is_number()) + return js[trayposition]; + else{ + printf("\nread motorboardparam error : feedmode!!! "); + return 0; + } + } + else{ + if(value < 0 || value > 2) + return 0; + auto js = getjson(); + if(!js[trayposition].is_null() && js[trayposition].is_number()) + { + js[trayposition] = value; + savejson(js); + } + return 0; + } +} + +void MotorboardParam::savejson(json js){ + remove(ParamPath.c_str()); + std::ofstream o(ParamPath); + o << std::setw(4) << js < lc(m_setlock); + json tmp = getjson(); + return json2struct(tmp); +} + +void MotorboardParam::SaveParam(MotorboardParam::MBParam param){ + std::lock_guard lc(m_setlock); + auto tmp = struct2json(param); + savejson(tmp); +} + +json MotorboardParam::getdefaultjson(){ + json m_json; + m_json[feed_mode] = 1; //0 low 1 mid 2 high + m_json[automaticcontrol_feedmode] = 0; + m_json[automaticcontrolfeedmode_threshold] = 0.5; + m_json[trayposition] = 0; + return m_json; +} + +json MotorboardParam::struct2json(MotorboardParam::MBParam param){ + json js; + js[feed_mode] = param.feedmode; //0 low 1 mid 2 high + js[automaticcontrol_feedmode] = param.automaticcontrolfeedmode; + js[automaticcontrolfeedmode_threshold] = param.automaticcontrolfeedmode_threshold; + js[trayposition] = param.trayposition; + return js; +} + +MotorboardParam::MBParam MotorboardParam::json2struct(json js){ + MotorboardParam::MBParam param{0}; + if(js[feed_mode].is_number()) + param.feedmode = js[feed_mode]; + else + param.feedmode = 1; + if(js[automaticcontrol_feedmode].is_number()) + param.automaticcontrolfeedmode = js[automaticcontrol_feedmode]; + else + param.automaticcontrolfeedmode = 0; + if(js[automaticcontrolfeedmode_threshold].is_number_float()) + param.automaticcontrolfeedmode_threshold = js[automaticcontrolfeedmode_threshold]; + else + param.automaticcontrolfeedmode_threshold = 0.5 ; + if(js[trayposition].is_number()) + param.trayposition = js[trayposition]; + else + param.trayposition = 0; + return param; +} + +json MotorboardParam::getjson(){ + if(access(JSON_CORRECTDIR_PATH,0) == -1) + { + auto ret = mkdir(JSON_CORRECTDIR_PATH, 0777); + if (ret != 0) + { + printf("make dir failed .path=%s \n", JSON_CORRECTDIR_PATH); + } + } + if (access(ParamPath.c_str(), F_OK) != 0) + { + auto cfs = getdefaultjson(); + savejson(cfs); + return cfs; + } + std::ifstream i(ParamPath); + auto pos = i.tellg(); + i.seekg(0, std::ios::end); + if (i.tellg() <= 2) + { + auto cfs = getdefaultjson(); + savejson(cfs); + return cfs; + } + i.seekg(pos); + json m_json; + i >> m_json; + i.close(); + return m_json; +} + diff --git a/device/gxx-linux/motorcontroller/MotorboardParam.h b/device/gxx-linux/motorcontroller/MotorboardParam.h new file mode 100644 index 0000000..89374bf --- /dev/null +++ b/device/gxx-linux/motorcontroller/MotorboardParam.h @@ -0,0 +1,39 @@ +#pragma once +#include +#include +#include +using json = nlohmann::json; + + +class MotorboardParam +{ +private: + const std::string ParamPath ="/usr/local/huago/motorboardparam.json"; + const std::string feed_mode = "feedmode"; + const std::string automaticcontrol_feedmode = "automaticcontrolfeedmode"; + const std::string automaticcontrolfeedmode_threshold = "automaticcontrolfeedmodethreshold"; + const std::string trayposition = "trayposition"; +public: + struct MBParam + { + int feedmode; + int automaticcontrolfeedmode; + float automaticcontrolfeedmode_threshold; + int trayposition; + }; + MotorboardParam(/* args */); + ~MotorboardParam(); + MotorboardParam::MBParam GetParam(); + void SaveParam(MotorboardParam::MBParam param); + int GetOrSetTrayPosition(bool isget,int value); + int GetOrSetFeedMode(bool isget,int value); + int GetOrSetEnableAutomaticControlFeedMode(bool isget,int value); +private: + void savejson(json js); + json struct2json(MotorboardParam::MBParam param); + MotorboardParam::MBParam json2struct(json js); + json getjson(); + json getdefaultjson(); + std::mutex m_setlock; +}; + diff --git a/device/gxx-linux/motorcontroller/Mt_Count.cpp b/device/gxx-linux/motorcontroller/Mt_Count.cpp new file mode 100644 index 0000000..ab206f1 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Count.cpp @@ -0,0 +1,26 @@ +#include "Mt_Count.h" + +Mt_Count::Mt_Count() +{ +} + +Mt_Count::~Mt_Count() +{ +} + +void Mt_Count::InitState(int state) +{ + printf("\nDis_Scan_Page %d",state); + display->DisplayState(DisType::Dis_Scan_Page,state,ClearScreen::BOT); +} + +IState *Mt_Count::OnState(StateInfo mode) +{ + return nullptr; +} + + +void Mt_Count::SetBtnCall(std::function call) +{ + +} \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/Mt_Count.h b/device/gxx-linux/motorcontroller/Mt_Count.h new file mode 100644 index 0000000..2ae3036 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Count.h @@ -0,0 +1,12 @@ +#pragma once +#include "IState.h" + +class Mt_Count : public IState +{ +public: + Mt_Count(/* args */); + virtual ~Mt_Count(); + virtual void InitState(int state=0) override; + virtual IState* OnState(StateInfo mode) override; + virtual void SetBtnCall(std::function call) override; +}; diff --git a/device/gxx-linux/motorcontroller/Mt_Error.cpp b/device/gxx-linux/motorcontroller/Mt_Error.cpp new file mode 100644 index 0000000..24bf43a --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Error.cpp @@ -0,0 +1,42 @@ +#include "Mt_Error.h" + +Mt_Error::Mt_Error() +{ + +} + +Mt_Error::~Mt_Error() +{ + +} + +void Mt_Error::InitState(int state) +{ + if(state == (int)HGScannerStatus::Mode_Error_Jam) + display->DisplayState(DisType::Dis_Err_JamIn,0,ClearScreen::All); + if(state == (int)HGScannerStatus::Mode_Error_DoublePaper) + display->DisplayState(DisType::Dis_Err_DoubleFeed,0,ClearScreen::All); + if(state == (int)HGScannerStatus::Mode_Error_Screw) + display->DisplayState(DisType::Dis_Err_PaperScrew,0,ClearScreen::All); + if(state == (int)HGScannerStatus::Mode_Error_Stable) + display->DisplayState(DisType::Dis_Err_Stable,0,ClearScreen::All); + if(state == (int)HGScannerStatus::Mode_Error_AquireTimeout) + display->DisplayState(DisType::Dis_Err_AqrImgTimeout,0,ClearScreen::All); + if(state == (int)HGScannerStatus::Mode_Error_CoverOpen) + display->DisplayState(DisType::Dis_Err_CoverOpen,0,ClearScreen::All); + if(state == (int)HGScannerStatus::Mode_Error_FeedError) + display->DisplayState(DisType::Dis_Err_FeedError,0,ClearScreen::All); + if(state == (int)HGScannerStatus::Mode_Error_NoFeed) + display->DisplayState(DisType::Dis_Err_NoPaper,0,ClearScreen::All); +} + +IState* Mt_Error::OnState(StateInfo mode) +{ + return nullptr; +} + + +void Mt_Error::SetBtnCall(std::function call) +{ + +} \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/Mt_Error.h b/device/gxx-linux/motorcontroller/Mt_Error.h new file mode 100644 index 0000000..e895dc1 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Error.h @@ -0,0 +1,12 @@ +#pragma once +#include "IState.h" + +class Mt_Error : public IState +{ +public: + Mt_Error(/* args */); + virtual ~Mt_Error(); + virtual void InitState(int state=0) override; + virtual IState* OnState(StateInfo mode) override; + virtual void SetBtnCall(std::function call) override; +}; \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/Mt_Idel.cpp b/device/gxx-linux/motorcontroller/Mt_Idel.cpp new file mode 100644 index 0000000..47b4165 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Idel.cpp @@ -0,0 +1,41 @@ +#include "Mt_Idel.h" +#include "Mt_Scan.h" +#include "Mt_Set.h" +#include "Mt_Count.h" +#include "Mt_Error.h" +#include "StateManager.h" + +Mt_Idel::Mt_Idel() +{ + +} + +Mt_Idel::~Mt_Idel() +{ + +} + +void Mt_Idel::InitState(int state) +{ + // display->DisplayState(DisType::Dis_Welcome,0); + // std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + display->DisplayState(DisType::Dis_Idel,0,ClearScreen::All); +} + +IState* Mt_Idel::OnState(StateInfo mode) +{ + if(mode.status == HGScannerStatus::Mode_Scan_Start) + return StateManager::GetState(); + if(mode.status == HGScannerStatus::Mode_Count) + return StateManager::GetState(); + if(mode.status == HGScannerStatus::Mode_Set_Key_Manual) + return StateManager::GetState(); + if(mode.status >= HGScannerStatus::Mode_Error_Jam && mode.status <= HGScannerStatus::Mode_Error_DogEar) + return StateManager::GetState(); + return this; +} + +void Mt_Idel::SetBtnCall(std::function call) +{ + +} \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/Mt_Idel.h b/device/gxx-linux/motorcontroller/Mt_Idel.h new file mode 100644 index 0000000..dbb4106 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Idel.h @@ -0,0 +1,14 @@ +#pragma once +#include "IState.h" + +class Mt_Idel: public IState +{ +private: + /* data */ +public: + Mt_Idel(/* args */); + virtual ~Mt_Idel(); + virtual void InitState(int state=0) override; + virtual IState* OnState(StateInfo mode) override; + virtual void SetBtnCall(std::function call) override; +}; diff --git a/device/gxx-linux/motorcontroller/Mt_Scan.cpp b/device/gxx-linux/motorcontroller/Mt_Scan.cpp new file mode 100644 index 0000000..a39d1b6 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Scan.cpp @@ -0,0 +1,27 @@ +#include "Mt_Scan.h" + +Mt_Scan::Mt_Scan() +{ + +} + +Mt_Scan::~Mt_Scan() +{ + +} + +void Mt_Scan::InitState(int state) +{ + display->DisplayState(DisType::Dis_Scan,0,ClearScreen::All); +} + +IState* Mt_Scan::OnState(StateInfo mode) +{ + return nullptr; +} + + +void Mt_Scan::SetBtnCall(std::function call) +{ + +} \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/Mt_Scan.h b/device/gxx-linux/motorcontroller/Mt_Scan.h new file mode 100644 index 0000000..1b42165 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Scan.h @@ -0,0 +1,12 @@ +#pragma once +#include "IState.h" + +class Mt_Scan: public IState +{ +public: + Mt_Scan(/* args */); + virtual ~Mt_Scan(); + virtual void InitState(int state=0) override; + virtual IState* OnState(StateInfo mode) override; + virtual void SetBtnCall(std::function call) override; +}; \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/Mt_Set.cpp b/device/gxx-linux/motorcontroller/Mt_Set.cpp new file mode 100644 index 0000000..be5c6d8 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Set.cpp @@ -0,0 +1,42 @@ +#include "Mt_Set.h" +#include "Mt_Idel.h" +#include "Mt_Scan.h" +#include "Mt_Set.h" +#include "Mt_Count.h" +#include "StateManager.h" +#include "MenuComponent.h" + +Mt_Set::Mt_Set() +{ + if(!m_menu.get()) + m_menu.reset(new MenuComponent()); +} + +Mt_Set::~Mt_Set() +{ +} + +void Mt_Set::InitState(int state) +{ + m_menu->initmenu(); + display->DisplayState(DisType::Dis_Set_ClearPaperPass, 0,ClearScreen::All); +} + +IState *Mt_Set::OnState(StateInfo mode) +{ + if (mode.status >= HGScannerStatus::Mode_Set_Key_ClearCount && + mode.status <= HGScannerStatus::Mode_Set_Key_Enter) + { + + return this; + } + else{ + + } + +} + +void Mt_Set::SetBtnCall(std::function call) +{ + m_call = call; +} \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/Mt_Set.h b/device/gxx-linux/motorcontroller/Mt_Set.h new file mode 100644 index 0000000..63f0572 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Set.h @@ -0,0 +1,20 @@ +#pragma once +#include "IState.h" + +class MenuComponent; + +class Mt_Set : public IState +{ +private: + /* data */ +public: + Mt_Set(/* args */); + virtual ~Mt_Set(); + virtual void InitState(int state=0) override; + virtual IState* OnState(StateInfo mode) override; + virtual void SetBtnCall(std::function call) override; +private: + std::function m_call; + std::shared_ptr m_menu; +}; + diff --git a/device/gxx-linux/motorcontroller/Mt_Welcome.cpp b/device/gxx-linux/motorcontroller/Mt_Welcome.cpp new file mode 100644 index 0000000..5b881c7 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Welcome.cpp @@ -0,0 +1,27 @@ +#include "Mt_Welcome.h" +#include "StateManager.h" +#include "Mt_Idel.h" + +Mt_Welcome::Mt_Welcome() +{ +} + +Mt_Welcome::~Mt_Welcome() +{ +} + +void Mt_Welcome::InitState(int state) +{ + display->DisplayState(DisType::Dis_Welcome,0,ClearScreen::All); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + display->DisplayState(DisType::Dis_Init,0,ClearScreen::All); +} + +IState *Mt_Welcome::OnState(StateInfo mode) +{ + return StateManager::GetState(); +} + +void Mt_Welcome::SetBtnCall(std::function call) +{ +} \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/Mt_Welcome.h b/device/gxx-linux/motorcontroller/Mt_Welcome.h new file mode 100644 index 0000000..adbda28 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Mt_Welcome.h @@ -0,0 +1,14 @@ +#pragma once +#include "IState.h" + +class Mt_Welcome:public IState +{ +private: + /* data */ +public: + Mt_Welcome(/* args */); + ~Mt_Welcome(); + virtual void InitState(int state=0) override; + virtual IState* OnState(StateInfo mode) override; + virtual void SetBtnCall(std::function call) override; +}; diff --git a/device/gxx-linux/motorcontroller/Selectable.h b/device/gxx-linux/motorcontroller/Selectable.h new file mode 100644 index 0000000..2a55c2e --- /dev/null +++ b/device/gxx-linux/motorcontroller/Selectable.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include +#include +#include +#include "Displaydef.h" + +using namespace std; + +class Selectable +{ +public: + enum class SettingType + { + Set_ClearPass = 1, + Set_Sleep, + Set_FeedStrength, + Set_Poweroff, + Set_ClearCount, + Set_CountMode, + Set_DoubleEn + }; + + enum class SleepTime + { + Sleep_15min = 1, + Sleep_30min, + Sleep_60min, + Sleep_120min, + Sleep_never + }; + + enum class MtStrength + { + Strength_Low = 1, + Strength_Mid, + Strength_High + }; + + + + Selectable() {} + virtual ~Selectable() {} + virtual string get_name() = 0; + virtual int select() = 0; + void setconfirmcall(std::function confirmcall) + { + g_call = confirmcall; + } + +protected: + std::function g_call; +}; diff --git a/device/gxx-linux/motorcontroller/StateControl.cpp b/device/gxx-linux/motorcontroller/StateControl.cpp new file mode 100644 index 0000000..9b4225c --- /dev/null +++ b/device/gxx-linux/motorcontroller/StateControl.cpp @@ -0,0 +1,404 @@ +#include "MenuComponent.h" +#include "DisplayCenter.h" +#include "keymonitor.h" +#include "regsaccess.h" +#include "StateControl.h" +#include "wakeup.hpp" +#include "MotorboardParam.h" + +StateControl::StateControl(std::shared_ptr m_regsAccess,std::shared_ptr wake):m_regs(m_regsAccess),m_wake(wake), +is_runing(false),is_cover_open(false),is_autopaper(false),en_autopaper_key(false){ + m_menu.reset(new MenuComponent()); + m_menu->initmenu(); + m_discenter.reset(new DisplayCenter()); + uint reg6value = 0; + m_regs->read(0x6,reg6value); + auto reg = *(reg6*)®6value; + MotorboardParam::MBParam mb_param = MotorboardParam().GetParam(); + reg.param.work_mode = 0; + reg.param.lift_init_set = mb_param.trayposition; + switch (mb_param.feedmode) + { + case 0: + reg.param.func_feed_low =1; + reg.param.func_feed_high = reg.param.func_feed_mid = 0; + break; + case 1: + reg.param.func_feed_mid =1; + reg.param.func_feed_high = reg.param.func_feed_low = 0; + break; + case 2: + reg.param.func_feed_high =1; + reg.param.func_feed_mid = reg.param.func_feed_low = 0; + break; + default: + reg.param.func_feed_mid =1; + reg.param.func_feed_high = reg.param.func_feed_low = 0; + break; + } + m_regs->write(0x6,reg.value); + auto keycall = [&](int keyvalye) + { + if(wake.get()) + wake->resettime(); + std::cout << "keycallback keyvalue= " << keyvalye << std::endl; + uint value = 0; + auto key = (KeyMonitor::HGKey)(keyvalye); + if((is_autopaper && (!en_autopaper_key)) || (is_autopaper && en_autopaper_key && (key!=KeyMonitor::HGKey::Key_Cancle))) + return ; + if((is_runing && key!=KeyMonitor::HGKey::Key_Cancle)||is_cover_open) + return ; + value = 0; + switch (key) + { + case KeyMonitor::HGKey::Key_Enter: + { + m_regs->read(0x6,value); + auto reg = *(reg6*)&value; + printf("\n reg.param.work_mode = %d ",reg.param.work_mode); + if(reg.param.work_mode !=1) + break; + m_regs->read(0x02,value); + if(!(value&0x10000)) + { + PutMsg(DisType::Dis_Err_NoPaper,0,ClearScreen::All); + break; + } + setrunstate(true); + reg.param.func_encount = 1; + m_regs->write(0x6,reg.value); + reg.param.func_encount = 0; + m_regs->write(0x6,reg.value); + if(m_wake.get()) + m_wake->setsleepfalg(true); + printf("\n m_menu->getcurindex() %d",m_menu->getcurindex()); + m_discenter->PutMsg(DisType::Dis_Set_Count,0,ClearScreen::All); + PutMsg(DisType::Dis_Scan_Page,getpapercount(),ClearScreen::BOT); + break; + } + case KeyMonitor::HGKey::Key_Cancle: + { + m_regs->read(0x06,value); + reg6 func = *(reg6*)&value; + m_menu->setcurindex(0); + m_discenter->PutMsg(func.param.work_mode == 0? (is_runing?DisType::Dis_Scan : DisType::Dis_Idel):(func.param.work_mode == 1?DisType::Dis_Set_Count:DisType::Dis_HandMode),0,ClearScreen::All); + if(m_discenter->getcurdistype() == DisType::Dis_Scan || m_discenter->getcurdistype() == DisType::Dis_Set_Count) + { + PutMsg(DisType::Dis_Scan_Page,getpapercount(),ClearScreen::BOT); + } + autopaperstop?autopaperstop():void(); + if(!is_runing) + break; + func.param.key_stop_enable = true; + m_regs->write(0x06,func.value); + func.param.key_stop_enable = false; + m_regs->write(0x06,func.value); + if(m_wake.get()) + m_wake->setsleepfalg(false); + //is_runing = false; + // if(int(m_discenter->getcurdistype()) > 4 && int(m_discenter->getcurdistype())<14) + // m_discenter->PutMsg(DisType::Dis_Idel,0,ClearScreen::All); + break; + } + case KeyMonitor::HGKey::Key_Count: + { + if(m_discenter->getcurdistype() != DisType::Dis_Idel) + { + m_menu->setcurindex(0); + m_discenter->PutMsg(DisType::Dis_Idel, 0,ClearScreen::All); + } + m_regs->read(0x6,value); + auto reg = *(reg6*)&value; + printf("\n reg.param.work_mode = %d ",reg.param.work_mode); + if(reg.param.work_mode!= 0 && reg.param.work_mode !=1) + break; + if(reg.param.work_mode == 1){ + reg.param.work_mode = 0; + m_keymonitor->setled(KeyMonitor::HGLed::Led_Count_close); + } + else{ + reg.param.work_mode = 1; + clearcount(); + getpapercount(); + PutMsg(DisType::Dis_Scan_Page,getpapercount(),ClearScreen::BOT); + m_keymonitor->setled(KeyMonitor::HGLed::Led_Count_open); + } + m_regs->write(0x6,reg.value); + m_discenter->PutMsg(reg.param.work_mode == 1?DisType::Dis_Set_Count:DisType::Dis_Idel,0, reg.param.work_mode == 1?ClearScreen::TOP : ClearScreen::All); + break; + } + // case KeyMonitor::HGKey::Key_Handle: + // { + // m_regs->read(0x6,value); + // auto reg = *(reg6*)&value; + // printf("\n reg.param.work_mode = %d ",reg.param.work_mode); + // if(reg.param.work_mode!= 0 && reg.param.work_mode !=5) + // break; + // if(reg.param.work_mode == 5){ + // reg.param.work_mode = 0; + // m_keymonitor->setled(KeyMonitor::HGLed::Led_Handle_close); + // } + // else{ + // reg.param.work_mode = 5; + // m_keymonitor->setled(KeyMonitor::HGLed::Led_Handle_open); + // } + // m_regs->write(0x6,reg.value); + // m_discenter->PutMsg(reg.param.work_mode == 5?DisType::Dis_HandMode:DisType::Dis_Idel,0,ClearScreen::All); + // break; + // } + case KeyMonitor::HGKey::Key_DoubleFeed: + { + m_regs->read(0x6,value); + auto reg = *(reg6*)&value; + printf("\n reg.param.key_endouble_feed =%d ",reg.param.key_endouble_feed); + if(reg.param.key_endouble_feed){ + reg.param.key_endouble_feed = 0; + m_keymonitor->setled(KeyMonitor::HGLed::Led_DoubleFeed_close); + } + else{ + reg.param.key_endouble_feed = 1; + m_keymonitor->setled(KeyMonitor::HGLed::Led_DoubleFeed_open); + } + m_regs->write(0x6,reg.value); + break; + } + case KeyMonitor::HGKey::Key_Left: + case KeyMonitor::HGKey::Key_Menu: + case KeyMonitor::HGKey::Key_Right: + { + m_regs->read(0x6,value); + auto reg = *(reg6*)&value; + if(reg.param.work_mode != 0) + break; + if(keyvalye == (int)KeyMonitor::HGKey::Key_Menu) + menu_func(m_menu->getcurtype()); + printf("\n m_menu->getcurindex() %d",m_menu->getcurindex()); + printf("\n mb 6 value%d",reg.value); + if(keyvalye == (int)KeyMonitor::HGKey::Key_Menu && m_menu->getcurindex() == 2) //2 分纸强度项 + m_menu->setcurindex(reg.param.func_feed_high?7:(reg.param.func_feed_mid?8:9)); //7 分纸强度高 8 分纸强度中 9 分纸强度弱 + else if(keyvalye == (int)KeyMonitor::HGKey::Key_Menu && m_menu->getcurindex() == 4) //2 分纸强度项 + m_menu->setcurindex(reg.param.lift_init_set == 2?20:(reg.param.lift_init_set == 1?21:22)); //7 分纸强度高 8 分纸强度中 9 分纸强度弱 + else + m_menu->option(keyvalye); + if(m_menu->getcurindex() >=7 && m_menu->getcurindex()<= 23) + m_discenter->PutMsg(m_menu->getcurtype(),0,ClearScreen::BOT); + else + m_discenter->PutMsg(m_menu->getcurtype(),0,ClearScreen::All); + break; + } + case KeyMonitor::HGKey::Key_Clear: + { + clearcount(); + if(m_discenter->getcurdistype() == DisType::Dis_Count_Page || m_discenter->getcurdistype() == DisType::Dis_Scan_Page) + m_discenter->PutMsg(DisType::Dis_Count_Page,0,ClearScreen::BOT); + break; + } + default: + break; + } + value = 0; + m_regs->read(0x6, value); + m_regs->write(0x6, value | 128); + m_regs->write(0x6, value & 0xffffff7f); + }; + m_keymonitor.reset(new KeyMonitor(keycall)); +} + +StateControl::~StateControl() +{ + uint value; + m_regs->read(0x06,value); + reg6 func = *(reg6*)&value; + func.param.key_stop_enable = true; + m_regs->write(0x06,func.value); + func.param.key_stop_enable = false; + m_regs->write(0x06,func.value); + if(m_menu.get()) + m_menu.reset(); + if(m_discenter.get()) + m_discenter.reset(); + if(m_keymonitor.get()) + m_keymonitor.reset(); +} + +void StateControl::PutMsg(DisType type,int value,ClearScreen clearscreen) +{ + if(m_discenter) + { + if(type == DisType::Dis_Idel) + { + uint value = 0; + m_regs->read(0x6,value); + auto tmp = *(reg6*)&value; + switch (tmp.param.work_mode) + { + case 1: + m_discenter->PutMsg(DisType::Dis_Set_Count,0,ClearScreen::All); + m_discenter->PutMsg(DisType::Dis_Scan_Page,getpapercount(),ClearScreen::BOT); + return ; + case 5: + m_discenter->PutMsg(DisType::Dis_HandMode,0,ClearScreen::All); + return; + default: + m_discenter->PutMsg(type,value,clearscreen); + break; + } + } + else + m_discenter->PutMsg(type,value,clearscreen); + } +} + +void StateControl::menu_func(DisType type) +{ + uint value = 0; + MotorboardParam func_feed; + m_regs->read(0x6,value); + auto tmp = *(reg6*)&value; + switch (type) + { + case DisType::Dis_Set_Poweroff: + system("poweroff"); + break; + case DisType::Dis_Set_ClearPaperPass: + tmp.param.func_clean_passthro = 1; + m_regs->write(0x6,tmp.value); + tmp.param.func_clean_passthro = 0; + m_regs->write(0x6,tmp.value); + break; + case DisType::Dis_Set_PollPI_High: + tmp.param.func_feed_high = 1; + tmp.param.func_feed_low = tmp.param.func_feed_mid = 0; + m_regs->write(0x6,tmp.value); + func_feed.GetOrSetFeedMode(false,2); + break; + case DisType::Dis_Set_PollPI_Mid: + tmp.param.func_feed_mid = 1; + tmp.param.func_feed_low = tmp.param.func_feed_high = 0; + m_regs->write(0x6,tmp.value); + func_feed.GetOrSetFeedMode(false,1); + break; + case DisType::Dis_Set_PollPI_Low: + tmp.param.func_feed_low = 1; + tmp.param.func_feed_mid = tmp.param.func_feed_high = 0; + m_regs->write(0x6,tmp.value); + func_feed.GetOrSetFeedMode(false,0); + break; + case DisType::Dis_Set_SleepMode_5M: + if(m_wake.get()) + m_wake->settime(300); + break; + case DisType::Dis_Set_SleepMode_10M: + if(m_wake.get()) + m_wake->settime(600); + break; + case DisType::Dis_Set_SleepMode_20M: + if(m_wake.get()) + m_wake->settime(1200); + break; + case DisType::Dis_Set_SleepMode_30M: + if(m_wake.get()) + m_wake->settime(1800); + break; + case DisType::Dis_Set_SleepMode_1H: + if(m_wake.get()) + m_wake->settime(3600); + break; + case DisType::Dis_Set_SleepMode_2H: + if(m_wake.get()) + m_wake->settime(7200); + break; + case DisType::Dis_Set_SleepMode_4H: + if(m_wake.get()) + m_wake->settime(14400); + break; + case DisType::Dis_Set_SleepMode_NEVER: + if(m_wake.get()) + m_wake->settime(-1); + break; + case DisType::Dis_Set_TrayPosition_High: + tmp.param.lift_init_set = 2; + m_regs->write(0x6,tmp.value); + func_feed.GetOrSetTrayPosition(false,2); + break; + case DisType::Dis_Set_TrayPosition_Mid: + tmp.param.lift_init_set = 1; + m_regs->write(0x6,tmp.value); + func_feed.GetOrSetTrayPosition(false,1); + break; + case DisType::Dis_Set_TrayPosition_Low: + tmp.param.lift_init_set = 0; + m_regs->write(0x6,tmp.value); + func_feed.GetOrSetTrayPosition(false,0); + break; + default: + break; + } +} + +void StateControl::lcdcontrol(int led){ + if(m_keymonitor) + m_keymonitor->setled((KeyMonitor::HGLed)led); +} + +void StateControl::setrunstate(bool value) +{ + is_runing = value; + if(is_runing){ + m_keymonitor->setled(KeyMonitor::HGLed::Led_Enter_open); + m_menu->setcurindex(0); + } + else + { + uint value = 0; + m_regs->read(0x6,value); + auto tmp = *(reg6*)&value; + m_keymonitor->setled(tmp.param.key_endouble_feed?KeyMonitor::HGLed::Led_DoubleFeed_open : KeyMonitor::HGLed::Led_DoubleFeed_close); + m_keymonitor->setled(KeyMonitor::HGLed::Led_Enter_close); + } +} + +bool StateControl::getrunstate() +{ + return is_runing; +} + +void StateControl::setcoverstate(bool value) +{ + is_cover_open = value; +} +bool StateControl::getcoverstate() +{ + return is_cover_open; +} +void StateControl::setmenuindex(int menu){ + m_menu->setcurindex(menu); +} + +uint StateControl::getpapercount(){ + unsigned int papercount = 0; + m_regs->read(0x02,papercount); + printf("\nmotorcount = %d ",papercount&0x3fff); + return papercount&0x3fff; +} + +void StateControl::clearcount(){ + uint value = 0; + m_regs->read(0x6,value); + auto reg = *(reg6*)&value; + reg.param.func_clear_count = 1; + m_regs->write(0x6,reg.value); + reg.param.func_clear_count = 0; + m_regs->write(0x6,reg.value); +} + +void StateControl::setautopaperflag(bool enable,bool enkey){ + is_autopaper = enable; + en_autopaper_key = enkey; +} + + void StateControl::setautopaperstopcallback(std::function func) + { + if(func) + autopaperstop = func; + } \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/StateControl.h b/device/gxx-linux/motorcontroller/StateControl.h new file mode 100644 index 0000000..eb95d1e --- /dev/null +++ b/device/gxx-linux/motorcontroller/StateControl.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include +class MenuComponent; +class DisplayCenter; +class KeyMonitor; +class IRegsAccess; +class WakeUp; +enum class DisType; +enum class ClearScreen; + +class StateControl{ +typedef union reg6 +{ + 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; +} REG6; + +public: + StateControl(std::shared_ptr m_regsAccess,std::shared_ptr wake); + ~StateControl(); + void PutMsg(DisType type,int value,ClearScreen clearscreen); + void setrunstate(bool value); + bool getrunstate(); + void setcoverstate(bool value); + bool getcoverstate(); + void setmenuindex(int menu); + void lcdcontrol(int led); + void setautopaperflag(bool enable,bool enkey); + void setautopaperstopcallback(std::function func); + +private: + void menu_func(DisType type); + uint getpapercount(); + void clearcount(); + std::shared_ptr m_menu; + std::shared_ptr m_discenter; + std::shared_ptr m_keymonitor; + std::shared_ptr m_regs; + std::shared_ptr m_wake; + std::function autopaperstop; + volatile bool is_runing; + volatile bool is_cover_open; + volatile bool is_autopaper; + volatile bool en_autopaper_key; +}; \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/StateManager.cpp b/device/gxx-linux/motorcontroller/StateManager.cpp new file mode 100644 index 0000000..9ee61c9 --- /dev/null +++ b/device/gxx-linux/motorcontroller/StateManager.cpp @@ -0,0 +1,4 @@ +#include "StateManager.h" + + +std::map> StatePreManager::motorState; \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/StateManager.h b/device/gxx-linux/motorcontroller/StateManager.h new file mode 100644 index 0000000..aa97a32 --- /dev/null +++ b/device/gxx-linux/motorcontroller/StateManager.h @@ -0,0 +1,30 @@ +#pragma once +#include "IState.h" +#include +#include + +class StatePreManager +{ +protected: + static std::map> motorState; +}; + + +template +class StateManager:public StatePreManager +{ +public: + StateManager(/* args */) = delete; + StateManager(const StateManager&) = delete; + StateManager& operator=(const StateManager&) = delete; + static IState* GetState(int state=0) + { + std::string type_name = typeid(T).name(); + std::map>::iterator iter = motorState.find(type_name); + if (iter == motorState.end()) { + motorState.insert(std::pair>(type_name, std::shared_ptr(new T))); + } + motorState[type_name]->InitState(state); + return motorState[type_name].get(); + } +}; diff --git a/device/gxx-linux/motorcontroller/Statedef.h b/device/gxx-linux/motorcontroller/Statedef.h new file mode 100644 index 0000000..8a62c1e --- /dev/null +++ b/device/gxx-linux/motorcontroller/Statedef.h @@ -0,0 +1,38 @@ +#pragma once + + enum class HGScannerStatus + { + Mode_Welcome, + Mode_Idel, + Mode_Count, + Mode_Scan_Start, + Mode_Scanning, + Mode_Error_Jam, + Mode_Error_DoublePaper, + Mode_Error_Screw, + Mode_Error_Stable, + Mode_Error_AquireTimeout, + Mode_Error_AquireFailed, + Mode_Error_NoFeed, + Mode_Error_CoverOpen, + Mode_Flatting, + Mode_Error_Size, + Mode_Error_DogEar, + Mode_Set_Key_ClearCount, + Mode_Set_Key_Left, + Mode_Set_Key_Manual, + Mode_Set_Key_Right, + Mode_Set_Key_Count, + Mode_Set_HandMode, + Mode_Set_Key_EnDoubleFeed, + Mode_Set_Key_Back, + Mode_Set_Key_Enter, //如需增加状态显示 在之后添加 请勿在此之前添加 避免影响其他代码 + Mode_Error_FeedError + }; + + struct StateInfo + { + HGScannerStatus status; + unsigned int value; + }; + \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/Subject.h b/device/gxx-linux/motorcontroller/Subject.h new file mode 100644 index 0000000..624dbd9 --- /dev/null +++ b/device/gxx-linux/motorcontroller/Subject.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include +#include +#include "Observer.h" + +using namespace std; + +class Subject +{ +public: + virtual ~Subject(){} + virtual void notify() = 0; + virtual void attach(Observer* this_observer) = 0; + virtual void dettach(Observer* this_observer) = 0; +}; \ No newline at end of file diff --git a/device/gxx-linux/motorcontroller/xmake.lua b/device/gxx-linux/motorcontroller/xmake.lua new file mode 100644 index 0000000..3931dbd --- /dev/null +++ b/device/gxx-linux/motorcontroller/xmake.lua @@ -0,0 +1,10 @@ +add_rules("mode.debug", "mode.release") + +target("motorcontroller") + set_kind("static") + add_files("*.cpp") + add_includedirs(".", { public = true}) + add_deps("regs","capimage","deviceio","display","applog","keymonitor") + add_includedirs("../scanner",{public = true}) + --add_includedirs("../capimage",{public = true}) + add_packages("common") \ No newline at end of file diff --git a/device/gxx-linux/out.text b/device/gxx-linux/out.text new file mode 100644 index 0000000..9a32dd3 --- /dev/null +++ b/device/gxx-linux/out.text @@ -0,0 +1 @@ +测试次数 = 1 异常次数 = 1 \ No newline at end of file diff --git a/device/gxx-linux/packages/common.pkg/include/StopWatch.h b/device/gxx-linux/packages/common.pkg/include/StopWatch.h index afa4ee9..bb8aede 100644 --- a/device/gxx-linux/packages/common.pkg/include/StopWatch.h +++ b/device/gxx-linux/packages/common.pkg/include/StopWatch.h @@ -1,5 +1,52 @@ #pragma once #include +#include + +static std::string GetCurrentTimeStamp(int time_stamp_type ) +{ + std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); + + std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); + std::tm* now_tm = std::localtime(&now_time_t); + + char buffer[128]; + strftime(buffer, sizeof(buffer), "%F %T", now_tm); + + std::ostringstream ss; + ss.fill('0'); + + std::chrono::milliseconds ms; + std::chrono::microseconds cs; + std::chrono::nanoseconds ns; + + switch (time_stamp_type) + { + case 0: + ss << buffer; + break; + case 1: + ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; + ss << buffer << ":" << ms.count(); + break; + case 2: + ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; + cs = std::chrono::duration_cast(now.time_since_epoch()) % 1000000; + ss << buffer << ":" << ms.count() << ":" << cs.count() % 1000; + break; + case 3: + ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; + cs = std::chrono::duration_cast(now.time_since_epoch()) % 1000000; + ns = std::chrono::duration_cast(now.time_since_epoch()) % 1000000000; + ss << buffer << ":" << ms.count() << ":" << cs.count() % 1000 << ":" << ns.count() % 1000; + break; + default: + ss << buffer; + break; + } + + return ss.str(); +} + class StopWatch { diff --git a/device/gxx-linux/packages/common.pkg/include/commondef.h b/device/gxx-linux/packages/common.pkg/include/commondef.h index 386b2ea..671b0b5 100644 --- a/device/gxx-linux/packages/common.pkg/include/commondef.h +++ b/device/gxx-linux/packages/common.pkg/include/commondef.h @@ -1,30 +1,20 @@ #pragma once #include #include -#include +#include + #define FWVersionEN -#define G400 +#define G100 #ifdef G200 -#define FWVersion "G2393A1215" +#define FWVersion "G2393C0322" #define SERIALNUM "G2396021071101" -#elif defined G300 -#define FWVersion "G3393C0303" -#define SERIALNUM "G3396021071101" -#elif defined G400 -#define FWVersion "G4393C0303" -#define SERIALNUM "G4396021071101" #else -#define FWVersion "G1393A1215" +#define FWVersion "G1393C0322" #define SERIALNUM "G1396021071101" #endif -#ifdef TEST_MODE -#define HG_SAVEIMG cv::imwrite -#else -#define HG_SAVEIMG -#endif //#ifdef FWVersionEN //#pragma warnning("WARNNING! current fareware version is :" FWVersion) //#endif @@ -116,13 +106,15 @@ struct MotorBoardGlue const std::function os_mode_call, const std::function set_sleepmode_call, const std::function mltop_call, - std::function auto_paper) + std::function auto_paper, + const std::function coveropen) : m_error_call(error_call), m_scan_done_call(scan_done_call), m_os_mode_call(os_mode_call), m_set_sleepmode_call(set_sleepmode_call), m_mltop_call(mltop_call), - m_auto_paper(auto_paper) + m_auto_paper(auto_paper), + m_coveropen_call(coveropen) { } @@ -132,11 +124,13 @@ struct MotorBoardGlue std::function m_set_sleepmode_call; std::function m_mltop_call; std::function m_auto_paper; + std::function m_coveropen_call; }; + struct ScannerNativeParam { - u32 TotalScanned; //扫描总计数 + u32 TotalScanned; //扫描总计�? u32 RollerNum; //滚轴计数 u32 H_ratio; //横向修正系数 u32 V_ratio; //纵向修正系数 @@ -144,16 +138,19 @@ struct ScannerNativeParam u32 FeedErrorTimes; //搓纸失败次数 u32 DoubleFeedTimes; //双张次数 u32 ScanSessionsCount; //总计扫描次数 - u16 gray_sp; //灰度sp值 - u16 color_sp; //彩色sp值 - int sleeptime; //休眠模式时间 -1 不休眠 - std::string SerialNum; //序列号 - std::string Token; //识别码 - u32 clr_maxbright; //彩色平场校正最大亮度 - u32 gray_maxbright; //灰度平场校正最大亮度 + u16 gray_sp; //灰度sp�? + u16 color_sp; //彩色sp�? + int sleeptime; //休眠模式时间 -1 不休�? + std::string SerialNum; //序列�? + std::string Token; //识别�? + u32 clr_maxbright; //彩色平场校正最大亮�? + u32 gray_maxbright; //灰度平场校正最大亮�? u32 speedmode; //速度模式 G100 0->70 1->80 2->90 3->100 G200 0->100 1->110 2->120 3->130 u16 Vid; //USB vid u16 Pid; //USB Pid + std::uint32_t chu_motor_speed_200; // G100 G200 出纸电机速度 + std::uint32_t chu_motor_speed_300; // G100 G200 出纸电机速度 + std::uint32_t chu_motor_speed_600; // G100 G200 出纸电机速度 }; enum TwSS : unsigned short @@ -260,7 +257,7 @@ struct HGSize } }; -//usb int 端点 返回消息的生产者 +//usb int 端点 返回消息的生产�? enum HGType { MtBoard = 1, @@ -273,7 +270,7 @@ enum HGType MBEvent, }; -//usb int 端点通信结构体 +//usb int 端点通信结构�? struct HGIntInfo { HGType From; @@ -283,9 +280,6 @@ struct HGIntInfo enum SpeedMode { - PPM40 = 40, - PPM50 = 50, - PPM60 = 60, PPM70 = 70, PPM80 = 80, PPM90 = 90, @@ -317,27 +311,30 @@ typedef struct static std::map cameraparmSp = { #ifdef G100 - {PPM70, {.colorSp_200 = 1341 , .graySp_200= 4030,.colorSp_300 = 1377 ,.graySp_300 = 4133,.colorSp_600 = 1701 ,.graySp_600 = 5105 , 1}}, - {PPM80, {.colorSp_200 = 1202 , .graySp_200= 3609,.colorSp_300 = 1230 ,.graySp_300 = 3691,.colorSp_600 = 1701 ,.graySp_600 = 5105 , 2}}, - {PPM90, {.colorSp_200 = 1024 , .graySp_200= 3072,.colorSp_300 = 1110 ,.graySp_300 = 3330,.colorSp_600 = 1701 ,.graySp_600 = 5105 , 0}}, - {PPM100, {.colorSp_200 = 847 , .graySp_200= 2541,.colorSp_300 = 1011 ,.graySp_300 = 3036,.colorSp_600 = 1701 ,.graySp_600 = 5105 , 3}},//G100 3399 暂无100 ppm - {PPM110, {.colorSp_200 = 847 , .graySp_200= 2541,.colorSp_300 = 1011 ,.graySp_300 = 3036,.colorSp_600 = 1701 ,.graySp_600 = 5105 , 3}}, -#elif defined G200 - {PPM100, {.colorSp_200 = 838 , .graySp_200= 2514,.colorSp_300 = 895 ,.graySp_300 = 2689,.colorSp_600 = 1705 ,.graySp_600 = 5117 , 0}}, - {PPM110, {.colorSp_200 = 838 , .graySp_200= 2514,.colorSp_300 = 895 ,.graySp_300 = 2689,.colorSp_600 = 1705 ,.graySp_600 = 5117 , 1}}, - {PPM120, {.colorSp_200 = 838 , .graySp_200= 2514,.colorSp_300 = 895 ,.graySp_300 = 2689,.colorSp_600 = 1705 ,.graySp_600 = 5117 , 3}}, - {PPM130, {.colorSp_200 = 838 , .graySp_200= 2514,.colorSp_300 = 895 ,.graySp_300 = 2689,.colorSp_600 = 1705 ,.graySp_600 = 5117 , 2}} //默认 140 -#elif defined G300 - {PPM40, {.colorSp_200 = 838 , .graySp_200= 2514,.colorSp_300 = 895 ,.graySp_300 = 2689,.colorSp_600 = 1705 ,.graySp_600 = 5117 , 0}}, - {PPM50, {.colorSp_200 = 838 , .graySp_200= 2514,.colorSp_300 = 895 ,.graySp_300 = 2689,.colorSp_600 = 1705 ,.graySp_600 = 5117 , 1}}, - {PPM60, {.colorSp_200 = 838 , .graySp_200= 2514,.colorSp_300 = 895 ,.graySp_300 = 2689,.colorSp_600 = 1705 ,.graySp_600 = 5117 , 2}}, - {PPM70, {.colorSp_200 = 838 , .graySp_200= 2514,.colorSp_300 = 895 ,.graySp_300 = 2689,.colorSp_600 = 1705 ,.graySp_600 = 5117 , 3}} //默认 140 + {PPM70, {.colorSp_200 = 1150 , .graySp_200= 3450,.colorSp_300 = 1207 ,.graySp_300 = 3621,.colorSp_600 = 1822 ,.graySp_600 = 5466 , 1}}, + {PPM80, {.colorSp_200 = 1150 , .graySp_200= 3450,.colorSp_300 = 1207 ,.graySp_300 = 3621,.colorSp_600 = 1822 ,.graySp_600 = 5466 , 2}}, + {PPM90, {.colorSp_200 = 944 , .graySp_200= 2834,.colorSp_300 = 1019 ,.graySp_300 = 3059,.colorSp_600 = 1822 ,.graySp_600 = 5466 , 0}}, + {PPM100, {.colorSp_200 = 847 , .graySp_200= 2541,.colorSp_300 = 875 ,.graySp_300 = 2626,.colorSp_600 = 1822 ,.graySp_600 = 5466 , 3}},//G100 3399 暂无100 ppm + {PPM110, {.colorSp_200 = 847 , .graySp_200= 2541,.colorSp_300 = 875 ,.graySp_300 = 2626,.colorSp_600 = 1822 ,.graySp_600 = 5466 , 3}}, #else - {PPM40, {.colorSp_200 = 2426 , .graySp_200= 7268,.colorSp_300 = 1615 ,.graySp_300 = 4849,.colorSp_600 = 1567 ,.graySp_600 = 4701 , 0}}, - {PPM50, {.colorSp_200 = 1950 , .graySp_200= 5870,.colorSp_300 = 1303 ,.graySp_300 = 3909,.colorSp_600 = 1567 ,.graySp_600 = 4701 , 1}}, - {PPM60, {.colorSp_200 = 1668 , .graySp_200= 5004,.colorSp_300 = 1080 ,.graySp_300 = 3248,.colorSp_600 = 1567 ,.graySp_600 = 4701 , 2}}, - {PPM70, {.colorSp_200 = 1287 , .graySp_200= 3864,.colorSp_300 = 859 ,.graySp_300 = 2477,.colorSp_600 = 1567 ,.graySp_600 = 4701 , 3}}, - {PPM80, {.colorSp_200 = 1245 , .graySp_200= 3735,.colorSp_300 = 830 ,.graySp_300 = 2490,.colorSp_600 = 1567 ,.graySp_600 = 4701 , 4}} + {PPM100, {.colorSp_200 = 816 , .graySp_200= 2450,.colorSp_300 = 878 ,.graySp_300 = 2637,.colorSp_600 = 1531 ,.graySp_600 = 4595 , 0}}, + {PPM110, {.colorSp_200 = 816 , .graySp_200= 2450,.colorSp_300 = 878 ,.graySp_300 = 2637,.colorSp_600 = 1531 ,.graySp_600 = 4595 , 1}}, + {PPM120, {.colorSp_200 = 816 , .graySp_200= 2450,.colorSp_300 = 878 ,.graySp_300 = 2637,.colorSp_600 = 1531 ,.graySp_600 = 4595 , 3}}, + {PPM130, {.colorSp_200 = 816 , .graySp_200= 2450,.colorSp_300 = 878 ,.graySp_300 = 2637,.colorSp_600 = 1531 ,.graySp_600 = 4595 , 2}} //默认 140 +#endif +}; + +static std::map anlogic_freq = { +#ifdef G100 + {PPM70, 1}, + {PPM80, 2}, + {PPM90, 3}, + {PPM110, 4}, +#else + {PPM100, 1}, + {PPM110, 2}, + {PPM120, 3}, + {PPM130, 4} #endif }; @@ -346,70 +343,39 @@ static std::map scannerSp = { {PPM70, {0x42d, 0xc88 , 1}}, {PPM80, {0x37f, 0xa7f, 2}}, {PPM90, {0x2B6, 0x822, 0}}, - //{PPM100, {0x27C, 0x775, 0}},//G100 3399 暂无100 ppm + {PPM100, {0x27C, 0x775, 0}},//G100 3399 暂无100 ppm {PPM110, {0x24e, 0x706, 3}}, -#elif defined G200 - {PPM100, {0x42d, 0xc88, 0}}, +#else + {PPM100, {0x27C, 0x775, 0}}, {PPM110, {0x27C, 0x775, 1}}, {PPM120, {0x27C, 0x775, 3}}, - {PPM130, {0x27C, 0x775, 2}}, //默认 140 -#elif defined G300 - {PPM40, {0x42d, 0xc88, 0}}, - {PPM50, {0x27C, 0x775, 1}}, - {PPM60, {0x27C, 0x775, 2}}, - {PPM70, {0x27C, 0x775, 3}}, -#else - {PPM40, {0x42d, 0xc88, 0}}, - {PPM50, {0x27C, 0x775, 1}}, - {PPM60, {0x27C, 0x775, 2}}, - {PPM70, {0x27C, 0x775, 3}}, - {PPM80, {0x42d, 0xc88, 4}}, + {PPM130, {0x27C, 0x775, 2}} //默认 140 #endif }; -#ifdef G300 -static std::map papersMap= { - {PaperSize::G400_A3, {1728, 11100}}, - {PaperSize::G400_A4, {1728, 8100}}, - {PaperSize::G400_A4R, {1728, 6000}}, - {PaperSize::G400_A5, {1728, 8100}}, - {PaperSize::G400_A5R, {1728, 8100}}, - {PaperSize::G400_A6, {1728, 8100}}, - {PaperSize::G400_A6R, {1728, 8100}}, - {PaperSize::G400_B4, {1728, 10800}}, - {PaperSize::G400_B5, {1728, 10800}}, - {PaperSize::G400_B5R, {1728, 6600}}, - {PaperSize::G400_B6, {1728, 6600}}, - {PaperSize::G400_B6R, {1728, 6600}}, - {PaperSize::G400_DOUBLELETTER, {1728, 10800}}, - {PaperSize::G400_B6R, {1728, 10800}}, - {PaperSize::G400_LEGAL, {1728, 11100}}, - {PaperSize::G400_LETTER, {1728, 11100}}, - {PaperSize::G400_MAXSIZE, {1728, 16002}}, - }; -#else static std::map papersMap = { - {PaperSize::G400_A3, {1632, 11100}}, - {PaperSize::G400_A4, {1632, 8400}}, - {PaperSize::G400_A4R, {1632, 6000}},//6000 - {PaperSize::G400_A5, {1632, 6600}}, - {PaperSize::G400_A5R, {1632, 4500}}, - {PaperSize::G400_A6, {1632, 4500}}, - {PaperSize::G400_A6R, {1632, 4500}}, - {PaperSize::G400_B4, {1632, 11100}}, - {PaperSize::G400_B5, {1632, 8400}}, - {PaperSize::G400_B5R, {1632, 6600}}, - {PaperSize::G400_B6, {1632, 6600}}, - {PaperSize::G400_DOUBLELETTER, {1632, 11100}}, - {PaperSize::G400_B6R, {1632, 6600}}, - {PaperSize::G400_LEGAL, {1632, 11100}}, - {PaperSize::G400_LETTER, {1632, 8400}}, - {PaperSize::G400_LETTERR, {1632, 11100}}, + {PaperSize::G400_A3, {1632, 10800}}, + {PaperSize::G400_A4, {1632, 8100}}, + {PaperSize::G400_A4R, {1632, 6000}}, + {PaperSize::G400_A5, {1632, 6000}}, + {PaperSize::G400_A5R, {1632, 6000}}, + {PaperSize::G400_A6, {1632, 6000}}, + {PaperSize::G400_A6R, {1632, 6000}}, + {PaperSize::G400_B4, {1632, 10800}}, + {PaperSize::G400_B5, {1632, 8100}}, + {PaperSize::G400_B5R, {1632, 6000}}, + {PaperSize::G400_B6, {1632, 6000}}, + {PaperSize::G400_DOUBLELETTER, {1632, 10800}}, + {PaperSize::G400_B6R, {1632, 6000}}, + {PaperSize::G400_LEGAL, {1632, 10800}}, + {PaperSize::G400_LETTER, {1632, 8100}}, + {PaperSize::G400_LETTERR, {1632, 10800}}, {PaperSize::G400_MAXSIZE, {1632, 16002}}, - {PaperSize::G400_AUTO, {1632, 11100}}, + {PaperSize::G400_AUTO, {1632, 10800}}, {PaperSize::G400_MAXAUTO, {1632, 16002}}, }; -#endif + +// pair unit:mm static std::map paperHeight={ {PaperSize::G400_A3, 475}, {PaperSize::G400_A4, 337}, @@ -427,10 +393,11 @@ static std::map paperHeight={ {PaperSize::G400_LEGAL, 386}, {PaperSize::G400_LETTER, 339}, {PaperSize::G400_LETTERR, 276}, - {PaperSize::G400_MAXSIZE, 1040},//300 dpi max heigth + {PaperSize::G400_MAXSIZE, 1040},//300 dpi max heigth 690 {PaperSize::G400_AUTO, 1040},//300 dpi max heigth {PaperSize::G400_MAXAUTO, 1040}//300 dpi max heigth }; + enum Scanner_Reg_Defs { SR_CMD, @@ -544,6 +511,14 @@ enum Scanner_Reg_Defs SR_SCAN_CNT, }; +typedef union Ctrol_Description{ + std::uint32_t value; + struct{ + std::uint32_t direction : 1; + std::uint32_t unused : 31; + }Param; +}CtrolDescription; + enum Updata_Stautus { Start_updata, @@ -686,6 +661,9 @@ STR(str2) #define S_INFO_SPEEDMODE "SpeedMode" #define S_INFO_VID "VID" #define S_INFO_PID "PID" +#define S_INFO_CHUZHI_MOTOR_SPEED_200 "Chu_Motor_Speed_200" +#define S_INFO_CHUZHI_MOTOR_SPEED_300 "Chu_Motor_Speed_300" +#define S_INFO_CHUZHI_MOTOR_SPEED_600 "Chu_Motor_Speed_600" #pragma pack(push) #pragma pack(4) @@ -763,8 +741,8 @@ typedef struct tagCrop_Rect int enable; int x; /*****自定义裁切区域左上角x坐标*/ int y; /*****自定义裁切区域左上角y坐标*/ - int width; /*****自定义裁切区域宽度*******/ - int height; /*****自定义裁切区域高度*******/ + int width; /*****自定义裁切区域宽�?******/ + int height; /*****自定义裁切区域高�?******/ }CropRect; typedef enum tagMulti_Output { @@ -791,67 +769,67 @@ typedef struct tagHhardware_Params_3399 struct GScanCap { - uint8_t papertype; /**< the current paper source ADF or Flatbed*/ - PaperAlign paperAlign; /**< 纸张放置方向*/ - uint8_t en_sizecheck; /**< 尺寸检测*/ - float imageRotateDegree; /**< 旋转角度*/ - uint8_t is_duplex; /**< True to use duplex false for simplex, ignored if flatbed*/ - uint8_t en_fold; /**< 对折*/ - int pixtype; /**< type of pixels to transfer image as */ - int automaticcolor; /**< 顔色自動識別*/ - int automaticcolortype; /**< 顔色自動識別后非彩色上傳類型*/ + uint8_t papertype; + PaperAlign paperAlign; + uint8_t en_sizecheck; + float imageRotateDegree; + uint8_t is_duplex; + uint8_t en_fold; + int pixtype; + int automaticcolor; + int automaticcolortype; //ScanRect scanrect; - float resolution_dst; /**< horizontal resolution */ - float resolution_native; /**< 实际扫描DPI*/ - float gamma; /**< Gamma */ - float contrast; /**< Contrast */ - float brightness; /**< Brightness */ - float threshold; /**< Threshold */ - uint8_t is_autocontrast; /**< 自动对比度*/ - uint8_t is_autocrop; /**< 自动裁切*/ - uint8_t is_autodiscradblank_normal; /**< 自动丢弃空白页通用*/ - int discardblank_percent; /**< 跳过空白页阀值*/ - uint8_t is_autodiscradblank_vince; /**< 自动丢弃空白页发票*/ - uint8_t is_switchfrontback; /**< 交换正反面*/ - uint8_t autodescrew; /**< 自动纠偏*/ - uint8_t multi_output_red; /**< 多流输出*/ - uint8_t hsvcorrect; /**< 答题卡除红*/ - uint8_t filter; /**< 除色*/ - uint8_t sharpen; /**< 锐化模糊*/ - uint8_t enhance_color; /**< 颜色增强*/ - uint8_t fillbackground; /**< 填黑框*/ - bool is_convex; /**< 填黑框模式,true为凸多边形填充,false为凹多边形填充,默认true*/ - int noise; /**< 除噪像素,能够消除noise宽度的背景竖条纹干扰,默认40*/ - int indent; /**< 轮廓缩进,裁剪、纠偏或者黑底填充时,对探索到的纸张轮廓进行缩进indent像素,默认5*/ - int AutoCrop_threshold; /**< 自动裁剪二值化阈值,取值范围(0, 255),默认40*/ - unsigned short scannum; /**< 扫描张数*/ - uint8_t is_backrotate180; /**< 背面旋转180*/ - uint8_t is_dogeardetection; /**< 折角检测*/ - HardwareCaps hardwarecaps; /**< 硬件扫描参数*/ - FillHole fillhole; /**< 穿孔移除>*/ - DetachNoise detachnoise; /**< 黑白降噪*/ - uint8_t is_autotext; /**< 自动文本方向识别 此处大小116字节*/ - bool isfillcolor; /**< 自动裁切颜色填充>*/ - int refuseInflow; /**< 防止渗透>*/ - int colorCorrection; /**< 色彩校正>*/ - int removeMorr; /**< 去除摩尔纹>*/ - int errorExtention; /**< 错误扩散>*/ - int textureRemove; /**< 除网纹>*/ - int splitImage; /**< 图像拆分>*/ - CropRect cropRect; /**< 自定义裁切>*/ - MultiOutput multiOutput; /**< 多流输出>*/ - bool normalCrop; /**< 自动裁切深色样张>*/ - uint32_t dogeardistabce; /**< 折角检测理论顶点到实际轮廓最新距离>*/ - bool fadeback; /**< 除底色>*/ - int fadebackrange; /**< 除底色范围>*/ - bool isuploadexceptionimage; /**< 是否上传双张报错后的异常图像>*/ - int fillholeratio_up; /**< 穿孔移除上下左右范围>*/ - int fillholeratio_down; + float resolution_dst; + float resolution_native; + float gamma; + float contrast; + float brightness; + float threshold; + uint8_t is_autocontrast; + uint8_t is_autocrop; + uint8_t is_autodiscradblank_normal; + int discardblank_percent; + uint8_t is_autodiscradblank_vince; + uint8_t is_switchfrontback; + uint8_t autodescrew; + uint8_t multi_output_red; + uint8_t hsvcorrect; + uint8_t filter; + uint8_t sharpen; + uint8_t enhance_color; + uint8_t fillbackground; + bool is_convex; + int noise; + int indent; + int AutoCrop_threshold; + unsigned short scannum; + uint8_t is_backrotate180; + uint8_t is_dogeardetection; + HardwareCaps hardwarecaps; + FillHole fillhole; + DetachNoise detachnoise; + uint8_t is_autotext; + bool isfillcolor; + int refuseInflow; + int colorCorrection; + int removeMorr; + int errorExtention; + int textureRemove; + int splitImage; + CropRect cropRect; + MultiOutput multiOutput; + bool normalCrop; + uint32_t dogeardistabce; + bool fadeback; + int fadebackrange; + bool isuploadexceptionimage; + int fillholeratio_up; + int fillholeratio_down; int fillholeratio_left; int fillholeratio_right; std::uint8_t fold_concatmode; /*拼接模式*/ int HsvFilterType; /**< 答题卡留红除杂色功能类型 暂定0 为关闭;1为留红除杂色>*/ bool is_colorcast; /**< 色偏校正>*/ - uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/ + uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/ }; -#pragma pack(pop) \ No newline at end of file +#pragma pack(pop) diff --git a/device/gxx-linux/packages/common.pkg/xmake.lua b/device/gxx-linux/packages/common.pkg/xmake.lua index 5f559dc..75057fb 100644 --- a/device/gxx-linux/packages/common.pkg/xmake.lua +++ b/device/gxx-linux/packages/common.pkg/xmake.lua @@ -1,5 +1,4 @@ -- 添加一个zlib包自动配置选项 - option("common") -- 设置是否在xmake f -h配置菜单中显示 diff --git a/device/gxx-linux/regs/serialib.cpp b/device/gxx-linux/regs/serialib.cpp index 0cb5aa9..c1d9abf 100644 --- a/device/gxx-linux/regs/serialib.cpp +++ b/device/gxx-linux/regs/serialib.cpp @@ -241,6 +241,7 @@ char serialib::Open(const char *Device,const unsigned int Bauds) options.c_cc[VTIME] = 0; // Timer unused options.c_cc[VMIN] = 0; // At least on character before satisfy reading tcsetattr(fd, TCSANOW, &options); // Activate the settings + tcflush(fd,TCIOFLUSH); return (1); // Success #endif } diff --git a/device/gxx-linux/regs/uartregaccessb.cpp b/device/gxx-linux/regs/uartregaccessb.cpp index e208543..2d6ed3b 100644 --- a/device/gxx-linux/regs/uartregaccessb.cpp +++ b/device/gxx-linux/regs/uartregaccessb.cpp @@ -2,11 +2,15 @@ #include "uartregaccessb.h" #include "serialib.h" #include "stringex.hpp" +#include UartRegsAccessB::UartRegsAccessB(std::string devName, int bauds, int readflag, int writeflag) { m_serial.reset(new serialib()); - m_serial->Open(devName.c_str(), bauds); + if(m_serial->Open(devName.c_str(), bauds) != 1){ + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + m_serial->Open(devName.c_str(), bauds); + } this->readflag = readflag; this->writeflag = writeflag; } @@ -33,11 +37,10 @@ bool UartRegsAccessB::read(unsigned int addr, unsigned int& val) pdata[0] = readflag; pdata[1] = (unsigned char)addr; m_serial->Write(bufRecv, 2); - if (m_serial->Read(bufRecv, 5, 500)) + if (m_serial->Read(bufRecv, 5, 200)) { val = *((unsigned int*)(bufRecv + 1)); return true; } - return false; } \ No newline at end of file diff --git a/device/gxx-linux/scanner/deviceconfig.cpp b/device/gxx-linux/scanner/deviceconfig.cpp index ff654f9..f4dbae2 100644 --- a/device/gxx-linux/scanner/deviceconfig.cpp +++ b/device/gxx-linux/scanner/deviceconfig.cpp @@ -61,8 +61,11 @@ 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 57a9f90..526a466 100644 --- a/device/gxx-linux/scanner/fsmstate.cpp +++ b/device/gxx-linux/scanner/fsmstate.cpp @@ -1,7 +1,7 @@ #include "fsmstate.h" -#include "iscanner.h" +#include "scanner.h" -IScanner *FsmState::scanner = NULL; +Scanner *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 1b8e55d..6091e79 100644 --- a/device/gxx-linux/scanner/fsmstate.h +++ b/device/gxx-linux/scanner/fsmstate.h @@ -4,7 +4,7 @@ #include #include -class IScanner; +class Scanner; enum ScanEvent { @@ -47,12 +47,12 @@ public: virtual FsmState* on_event(ScanEvent event) = 0; virtual void initial() {} - static void setScanner(IScanner* scan) { + static void setScanner(Scanner* scan) { scanner = scan; } std::string typeName = "FsmState"; protected: - static IScanner* scanner; + static Scanner* scanner; }; diff --git a/device/gxx-linux/scanner/iimagehandler.h b/device/gxx-linux/scanner/iimagehandler.h index eaf1c9b..9699441 100644 --- a/device/gxx-linux/scanner/iimagehandler.h +++ b/device/gxx-linux/scanner/iimagehandler.h @@ -16,13 +16,8 @@ static std::map papersize{ {B4, Size{250, 353}}, {B5, Size{176, 250}}, {B6, Size{125, 176}}, -#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}}, @@ -37,7 +32,7 @@ class IImageHandler { public: virtual ~IImageHandler() {} - virtual void add_image(void *data, int width, int height, int type,int scannnum,std::uint32_t fpga_vs,CISVendor cistype) = 0; + virtual void add_image(void *data, int width, int height, int type,int scannnum,unsigned int fpgaversion=0x00090001) = 0; virtual void config_procparams(HGImgProcParms params) = 0; virtual void add_scanevent(HGIntInfo status) = 0; virtual void clear() = 0; @@ -74,18 +69,14 @@ public: bool set_config(GScanCap config) { - m_hgimgconfig = 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) + 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()) { @@ -96,22 +87,26 @@ public: } if(config.fillhole.is_fillhole) { - if((config.fillholeratio_down+config.fillholeratio_up+config.fillholeratio_left+config.fillholeratio_right)>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))); + printf(" \nconfig.fillholeratio -----"); } 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 || config.papertype == 0; + bool islongcustomcrop = config.papertype == 52; //bool isautocrop = config.papertype == TwSS::None; Size fixedSize; - printf(" \nconfig.dogeardistabce=%d", config.dogeardistabce); + printf(" \nconfig.fillholeratio_down=%d", config.fillholeratio_down); + printf(" \nconfig.fillholeratio_up=%d", config.fillholeratio_up); + printf(" \nconfig.fillholeratio_left=%d", config.fillholeratio_left); + printf(" \nconfig.fillholeratio_right=%d", config.fillholeratio_right); printf(" \nconfig.papertype=%d", config.papertype); printf(" \nconfig.AutoCrop_threshold=%d", config.AutoCrop_threshold); printf(" \nconfig.autodescrew=%d", config.autodescrew); @@ -124,12 +119,12 @@ public: printf(" \nconfig.enhance_color=%d", config.enhance_color); printf(" \nconfig.fillbackground=%d", config.fillbackground); printf(" \nconfig.filter=%d", config.filter); + printf(" \nconfig.HsvFilterType=%d", config.HsvFilterType); printf(" \nconfig.fillhole.is_fillhole=%d", config.fillhole.is_fillhole); printf(" \nconfig.gamma=%f", config.gamma); 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); @@ -149,14 +144,12 @@ public: 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, 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))); + // 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) { @@ -176,14 +169,13 @@ public: 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.pixtype == 2)&&(config.is_colorcast)) + { + printf("\n 色偏"); + m_ials.push_back(m_colorcast); + } - // if (config.fadeback && config.pixtype > 0)// && config.pixtype == 2 + if (config.fadeback && config.pixtype > 0)// && config.pixtype == 2 { printf("\n 除底色"); m_ials.push_back(shared_ptr(new CImageApplyFadeBackGroudColor(50,0,config.fadebackrange))); @@ -304,24 +296,21 @@ public: 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; } @@ -332,5 +321,5 @@ protected: std::vector> m_ials; std::shared_ptr m_dog; std::shared_ptr m_sizedetect; - // std::shared_ptr m_colorcast; + std::shared_ptr m_colorcast; }; diff --git a/device/gxx-linux/scanner/imagesavehandler.cpp b/device/gxx-linux/scanner/imagesavehandler.cpp index be9cda1..80ece6c 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,std::uint32_t fpga_vs,CISVendor cistype) +void ImageSaveHandler::add_image(void *data, int width, int height, int type, int scannnum,unsigned int fpgaversion) { 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 5bf1c81..2082e0b 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,std::uint32_t fpga_vs,CISVendor cistype); + virtual void add_image(void* data, int width, int height, int type ,int scannnum,unsigned int fpgaversion); virtual bool done(); private: diff --git a/device/gxx-linux/scanner/imageusbhandler.cpp b/device/gxx-linux/scanner/imageusbhandler.cpp index 7d127ae..0bca491 100644 --- a/device/gxx-linux/scanner/imageusbhandler.cpp +++ b/device/gxx-linux/scanner/imageusbhandler.cpp @@ -10,198 +10,154 @@ #include "imageencode.h" #include #include "ImageApplyAutoCrop.h" +#include "ImageApplyColorCastCorrect.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) { LOG_INIT(); this->images = images; - m_dog.reset(new CImageApplyDogEarDetection(40, 1.0, 50)); - // m_colorcast.reset(new CImageApplyColorCastCorrect()); + m_dog.reset(new CImageApplyDogEarDetection(40,1.0,50)); + m_colorcast.reset(new CImageApplyColorCastCorrect(CImageApplyColorCastCorrect::CIS_DN_PATCH1)); 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) -{ - 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; +} +static int num = 0; +void ImageUsbHandler::add_image(void *data, int width, int height, int type, int scannnum,unsigned int fpgaversion) +{ + printf("ImageUsbHandler::add_image(%d * %d), fpgaversion = %d\n", width, height, fpgaversion); + + if(images->push_raw(data, width, height, type == CV_8UC1 ? COLOR_CHANNEL_GRAY : COLOR_CHANNEL_RGB, scannnum, fpgaversion, 0)) + { + return; + } - memset(&pkimg, 0, sizeof(pkimg)); - pkimg.pos.paper_ind = scannnum; - pkimg.pos.status = IMG_STATUS_OK; - pkimg.pos.paper_side = PAPER_SIDE_LEFT; + images->push(nullptr, false); // notify ONE paper passed + // img_one_paper *paper = new img_one_paper(); + // paper->init_from(data, width, height, scannnum, PAPER_SIDE_LEFT, type == CV_8UC1 ? COLOR_CHANNEL_GRAY : COLOR_CHANNEL_RGB); + // imgproc_->push_image(paper); + // paper->release(); + 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(); - printf("Image %d parameters: %d * %d * %d\n", scannnum, mat.cols, mat.rows, mat.channels() * 8); + mat = cv::Mat(height, width, CV_8UC1, data).clone(); capture_data.Put(mat); StopWatch checktime; - add_que_count(); - results.emplace( - pool.enqueue([this, width, height, type, ext, scannnum, data, cistype] - { - 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); + 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; + auto mergemat = GetMergeMat(type == CV_8UC1 ? width : width / 3, height, type, tmp,fpgaversion); + 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); #else - int dstwidth = type==CV_8UC1?width:width/3; - cv::Mat saveMat =GetMergeMat(dstwidth, height, type,mat,0x90001); + cv::resize(mergemat,mergemat,cv::Size(0,0),200.0 / 600.0,1.432323/3); #endif - 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_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); + results.emplace( + pool.enqueue([this, width, height, type, ext, scannnum, data ,fpgaversion] + { + printf("enqueue image index %d \n",scannnum); + StopWatch sw; + cv::Mat mat = capture_data.Take(); + + int dstwidth = type==CV_8UC1?width:width/3; + static int it=0; + StopWatch sss; + cv::Mat saveMat =GetMergeMat(dstwidth, height, type,mat,fpgaversion); + printf("\n Merge time %f fpgaversion %d \n",sss.elapsed_ms(),fpgaversion); + //cv::imwrite("/home/"+to_string(it++)+".bmp",saveMat); + //int dpi = saveMat.cols==7344?2:3; if(!m_scanconfig.g200params.pc_correct) - correctColor(saveMat,dpi,saveMat.channels()==3?1:0,!m_scanconfig.g200params.is_textcorrect); + correctColor(saveMat,m_scanconfig.g200params.dpi,saveMat.channels()==3?1:0,!m_scanconfig.g200params.is_textcorrect); printf("\n correctColor time %f \n",sw.elapsed_ms()); + + // if((H_ratio != 1.0f) || (V_ratio != 1.0f)) + // cv::resize(saveMat,saveMat,cv::Size(),H_ratio,V_ratio); encode_data.Put(saveMat); - add_que_count(); - encodeimgs.push(encodepools.enqueue([this,width,height,type,cistype]() -> std::vector + + encodeimgs.push(encodepools.enqueue([this,width,height,type]() -> 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) V_ratio=1.0f; - if(m_scanconfig.g200params.dpi==0x01) + if(m_scanconfig.g200params.dpi==1) { - cv::resize(saveMat,saveMat,cv::Size(0,0),200.0/300.0*H_ratio,1.0*V_ratio); + cv::resize(saveMat,saveMat,cv::Size(0,0),200.0/300.0*H_ratio,1.0*V_ratio); } if(m_scanconfig.g200params.dpi == 2) { - if((H_ratio != 1.0f) || (V_ratio != 1.0f)) - cv::resize(saveMat,saveMat,cv::Size(),H_ratio,V_ratio); + if((H_ratio != 1.0f) || (V_ratio != 1.0f)) + cv::resize(saveMat,saveMat,cv::Size(0,0),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�ɼ� + #else cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.432323*V_ratio); -#elif defined G400 - cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.5*V_ratio); -#else - cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.432323*V_ratio); -#endif - printf("dpi = %d, image = %d * %d * %d\n", m_scanconfig.g200params.dpi, saveMat.cols, saveMat.rows, saveMat.channels() * 8); - + #endif cv::Mat imageMat; std::vector imgs; int actwidth = saveMat.cols / 2; @@ -214,14 +170,11 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int imgs.push_back(imageMat); } } - // imgs.push_back(saveMat); - std::shared_ptr imageencode; //(new BmpImageEncode()); - std::vector encodedata; - //bool iscorrect_mode =true; - //if(!iscorrect_mode) + std::shared_ptr imageencode; //(new BmpImageEncode()); + std::vector encodedata; if (!m_scanconfig.g200params.iscorrect_mode) { - if (!m_hgimgconfig.is_switchfrontback && (imgs.size() > 1)) + if (m_hgimgconfig.is_switchfrontback && (imgs.size() > 1)) std::swap(imgs[0], imgs[1]); CImageApply* ptr = m_ials[0].get(); if (typeid(*ptr) != typeid(CImageApplyOutHole)){ @@ -231,15 +184,14 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int cv::flip(imgs[1], imgs[1], 1); } } + for (auto &ialsnode : m_ials) { ialsnode->apply(imgs, bool(m_hgimgconfig.is_duplex)); } - if ((!m_hgimgconfig.is_duplex) && (imgs.size() > 1)) imgs.pop_back(); - else if((imgs.size() > 1) && (cistype == CISVendor::HUALIN_CIS_V0)) - cv::flip(imgs[1], imgs[1], 0); + } for (auto &img : imgs) @@ -255,8 +207,7 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int if(m_scanconfig.g200params.iscorrect_mode) imageencode.reset(new JpegImageEncode(false, m_hgimgconfig.resolution_dst)); else - imageencode.reset(new JpegImageEncode(m_scanconfig.g200params.color?false:true, m_hgimgconfig.resolution_dst)); - + imageencode.reset(new JpegImageEncode(m_hgimgconfig.pixtype == 0, m_hgimgconfig.resolution_dst)); encodedata.push_back(imageencode->encode(enMat)); } } @@ -270,28 +221,18 @@ 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())); })); } } -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) { @@ -299,7 +240,7 @@ bool ImageUsbHandler::is_limit() { results.front().get(); { - // std::lock_guard guard(mtx); + //std::lock_guard guard(mtx); results.pop(); } } @@ -310,62 +251,31 @@ bool ImageUsbHandler::is_limit() } else { - while (results.size() >= 20) + while (results.size() >= 15) { results.front().get(); { - // std::lock_guard guard(mtx); + //std::lock_guard guard(mtx); results.pop(); } } - if (encodeimgs.size() >= 20) + if (encodeimgs.size() >= 15) { + //printf("\n encodeimgs size = %d ", encodeimgs.size()); return true; } } 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()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(3)); - } - push_event(ev); -} -void ImageUsbHandler::push_event(HGIntInfo ev) +void ImageUsbHandler::add_scanevent(HGIntInfo status) { VectorMemroyPtr mem = VectorMemroyPtr(new VectorMemroy()); - HGIntInfo info = ev; + HGIntInfo info = status; mem->resize(sizeof(info)); memcpy(&mem->buf()[0], &info, sizeof(info)); images->push(mem, false); } -int32_t ImageUsbHandler::add_que_count(int adden) -{ - std::lock_guard lock(proc_que_); - - que_len_ += adden; - - return que_len_; -} - -void ImageUsbHandler::add_scanevent(HGIntInfo status) -{ - printf("add_scanevent(%d)\n", status.From); - if (status.From == STOPSCAN && !done()) - { - 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)); - } - else - { - push_event(status); - } -} void ImageUsbHandler::clear() { @@ -378,40 +288,14 @@ 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)); - V_ratio = 1.0f; + H_ratio =*((float*)(&h_ratio)); + V_ratio =*((float*)(&v_ratio)); } bool ImageUsbHandler::done() { - // 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)); - // } - // } - - // return over; std::lock_guard guard(mtx); if(results.size() >= 1){ auto &fu_run = results.back(); @@ -427,7 +311,6 @@ bool ImageUsbHandler::done() 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 true; } @@ -443,61 +326,3 @@ 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/imageusbhandler.h b/device/gxx-linux/scanner/imageusbhandler.h index b424955..1afa01d 100644 --- a/device/gxx-linux/scanner/imageusbhandler.h +++ b/device/gxx-linux/scanner/imageusbhandler.h @@ -9,22 +9,17 @@ class UsbImageProcQueue; +class img_processor; class ImageUsbHandler: public IImageHandler { - void push_event(HGIntInfo ev); - void thread_push_stop_event(HGIntInfo ev); - int32_t add_que_count(int adden = 1); - - std::shared_ptr stop_event_thread_; - std::mutex proc_que_; - volatile int32_t que_len_; - + img_processor* imgproc_; + public: ImageUsbHandler(std::shared_ptr images = nullptr); virtual ~ImageUsbHandler(); virtual void config_procparams(HGImgProcParms params); - virtual void add_image(void* data, int width, int height, int type,int scannnum,std::uint32_t fpga_vs,CISVendor cistype); + virtual void add_image(void* data, int width, int height, int type,int scannnum,unsigned int fpgaversion) override; virtual void add_scanevent(HGIntInfo status); virtual bool done(); virtual void clear(); diff --git a/device/gxx-linux/scanner/imageusbtesthandler.cpp b/device/gxx-linux/scanner/imageusbtesthandler.cpp index 2ebd7bc..7b6d616 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,std::uint32_t fpga_vs,CISVendor cistype) +void ImageUsbTestHandler::add_image(void* data, int width, int height, int type ,int scannnum,unsigned int fpgaversion) { // 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 7d87b5d..af18a83 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,std::uint32_t fpga_vs,CISVendor cistype); + virtual void add_image(void* data, int width, int height, int type,int scannnum,unsigned int fpgaversion); }; \ No newline at end of file diff --git a/device/gxx-linux/scanner/iscanner.cpp b/device/gxx-linux/scanner/iscanner.cpp deleted file mode 100644 index 4c1cef0..0000000 --- a/device/gxx-linux/scanner/iscanner.cpp +++ /dev/null @@ -1,344 +0,0 @@ -#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 index 5abc5ff..8c44b23 100644 --- a/device/gxx-linux/scanner/iscanner.h +++ b/device/gxx-linux/scanner/iscanner.h @@ -1,71 +1,45 @@ #pragma once #include -#include +#include +#include "commondef.h" #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; + virtual ~IScanner(){} + virtual void try_scan(const std::string encodehexstr) = 0; + virtual void configparam(HGScanConfig config)=0; + virtual void start_scan()=0; + virtual void stop_scan()=0; + virtual int count()=0; + virtual int mode()=0; + virtual void put(ScanEvent evt)=0; + virtual bool is_runscan()=0; + virtual void set_imagehandler(std::shared_ptr handler = nullptr)=0; + virtual void clear_error()=0; + virtual bool paper_ready()=0; + virtual bool get_keeplastpaper()=0; + virtual void set_motorboardcallback(MotorBoardGlue glue)=0; + virtual void set_imgprocparams(HGImgProcParms parmas)=0; + virtual void test_autocorrect(int colormode)=0; + virtual void test_cap(HGScanConfig config)=0; + virtual bool set_hgimgconfig(GScanCap config)=0; + virtual void add_scansever(HGIntInfo event)=0; + virtual void set_sleeptime(int val)=0; + virtual int get_sleeptime()=0; + virtual void resettime()=0; + virtual int get_sleepstatus()=0; + virtual void set_sleepstatus(bool off)=0; + virtual int getimageprocedone()=0; + virtual void set_paprent(void* parent)=0; + virtual bool getpaperon()=0; + virtual int getmbstatus()=0; + virtual void setfeedmode(int value)=0; + virtual void settrayposition(int value)=0; + virtual std::string getmbversion()=0; + virtual void clean_paper_road() = 0; }; diff --git a/device/gxx-linux/scanner/scanner.cpp b/device/gxx-linux/scanner/scanner.cpp index abbf90b..821694c 100644 --- a/device/gxx-linux/scanner/scanner.cpp +++ b/device/gxx-linux/scanner/scanner.cpp @@ -1,6 +1,6 @@ #include "scanner.h" #include -#include "Imotorboard.h" +#include "motorboard.h" #include "Capturer.h" #include #include "StopWatch.h" @@ -10,14 +10,33 @@ #include "fpgacontrol.h" #include "scannerregs.h" #include "fpgacontrol.h" -#include "Gpio.h" +#include "Displaydef.h" +#include "CImageMerge.h" #include "correct_ultis.h" +#include "SysInforTool.h" +#include "MotorboardParam.h" +#include "FeedControl.h" +#include "deviceconfig.h" +#include +#include +#include +#include static const std::string loggername = "Scanner"; -Scanner::Scanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake):IScanner(capturer,mb,wake) +Scanner::Scanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake) + : bMsgLoop(true), + scancount(1024), + mfpgaversion(0x00090001) { LOG_INIT(); + this->wake = wake; + this->mb = mb; + this->capturer = capturer; + capturer->regs()->read(15, mfpgaversion); + cout << "mfpgaversion :" << mfpgaversion << endl; + SysInforTool(ScannerSysInfo()).GetSysInfo(); + // threadRunMessageLoop = std::move(std::thread(&Scanner::runMessageLoop, this)); auto mb_error_call = [&](unsigned int error_code) { int code = 0; @@ -35,16 +54,19 @@ Scanner::Scanner(std::shared_ptr capturer, std::shared_ptr capturer, std::shared_ptradd_scanevent(errType); + if (imagehandler.get()) + imagehandler->add_scanevent(errType); done_scan = 1; } - - mb_error_code = code; - if (code != 0) - done_scan = 1; + mb_error_code = error_code; }; auto mb_scandone_call = [&]() { done_scan = 1; + if(mb_error_code == 0) + mb_error_code = 0xffffffff; printf("motorboard callback scan_done"); + imagehandler->add_scanevent({.From = STOPSCAN, .Code = mb_error_code}); }; auto mb_osmode_call = [&](unsigned int osmode) @@ -92,6 +115,22 @@ Scanner::Scanner(std::shared_ptr capturer, std::shared_ptradd_scanevent(errType); + done_scan = 1; + } + else + { + printf("\n cover closed "); + LOG_TRACE("cover closed \n"); + } + }; auto mb_set_sleeptime_call = [&](unsigned int speedmode) { printf("\n mb_set_sleeptime_call val= %d ", speedmode); @@ -131,47 +170,246 @@ Scanner::Scanner(std::shared_ptr capturer, std::shared_ptris_runing()) return; start_scan(); }; - MotorBoardGlue mb_glue = {mb_error_call, mb_scandone_call, mb_osmode_call, mb_set_sleeptime_call, mb_mltop_call, mb_auto_paper}; + + MotorBoardGlue mb_glue = {mb_error_call, mb_scandone_call, mb_osmode_call, mb_set_sleeptime_call, mb_mltop_call, mb_auto_paper, mb_coveropen_call}; mb->set_callbacks(mb_glue); - mb->set_auto_paper(m_config.g200params.is_autopaper); //防止程序异常死掉后未关闭连续扫描导致升降台抬升扫描 + mb->PutMsg(DisType::Dis_Idel, 0, ClearScreen::All); + 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()}; + if (imagehandler.get()) + imagehandler->add_scanevent(info); + if (s_info.length() > 0) + ((ScannerRegAccess *)m_parent)->write_info(s_info); + }; + this->capturer->setcapturecall(capturecallback); + mb->set_auto_paper(false, false); //防止程序异常死掉后未关闭连续扫描导致升降台抬升扫描 + mb->setautopaperkeystopcallback([&]{ + if (m_config.g200params.is_autopaper) + imagehandler ? imagehandler->add_scanevent({.From = STOPSCAN, 1}) : void(0); + handstop = true; }); + // mb->set_speed_mode(2); u32 value; mb->read(0x00, value); printf("mb reg[0] = %d \n", value); value = 0; mb->read(0x03, value); - if (value >= 35211210) - m_mbver = MotorVersion::Motor_paperout; - else if(value >= 35211126) - m_mbver = MotorVersion::Motor_mltop; - else - m_mbver = MotorVersion::Motor_old; mbversion = std::to_string(value); - printf("mb reg[0] = %d \n", value); + printf("mb reg[3] = %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(); +} + +std::string Scanner::getmbversion() +{ + u32 value = 0; + mb->read(0x03, value); + mbversion = std::to_string(value); + return mbversion; +} + +void Scanner::startcapimage(bool value) +{ + FILE *fp = fopen("/sys/class/tty/ttyUSB0/device/huagao_scanner", "w"); + if (fp == NULL) + perror("startcapimage open filed"); + else + { + fprintf(fp, "%d", value ? 1 : 0); + fclose(fp); + } +} + +bool Scanner::getcapimageflag() +{ + int ret = 1; + FILE *fp = fopen("/sys/class/tty/ttyUSB0/device/huagao_scanner", "r"); + if (fp == NULL) + perror("startcapimage open filed"); + else + { + fscanf(fp, "%d", &ret); + fclose(fp); + } + printf("\ngetcapimageflag %d", ret); + return ret == 0 ? false : true; +} + +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 (config.resolution_dst < 300) + m_config.g200params.dpi = 1; + else if (config.resolution_dst < 500) + m_config.g200params.dpi = 2; + else + m_config.g200params.dpi = 3; + + 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; + printf("\n ********m_config.g200params.paper %d", m_config.g200params.paper); + if (imagehandler.get()) + { + imagehandler->clear(); + return imagehandler->set_config(config); + } + printf("\n done setting set_hgimgconfig"); + 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; + } + printf("\nconfigparam done\n"); +} + +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}); + mb->PutMsg(DisType::Dis_Device_Lock, 0, ClearScreen::All); + } } void Scanner::start_scan() { - printf("\n ------------------start_scan------------------ \n"); - if (is_runscan()) + printf("\n ------------------m_config.g200params.paper %d", m_config.g200params.paper); + LOG_TRACE("\n ------------------start_scan------------------ \n"); + capturer->regs()->read(15, mfpgaversion); + cout << "start_scan mfpgaversion :" << mfpgaversion << endl; + 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()) + { + if (m_config.g200params.is_autopaper) + imagehandler->add_scanevent({.From = STOPSCAN, 1}); return; + } if (wake.get()) wake->setsleepfalg(true); - mb_error_code = is_ml_top = handstop = false; + mb->SetKeyState(true); + is_ml_top = handstop = false; + mb_error_code = 0; FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color); capturer->open(m_config,fpgaparam); + + if (m_config.g200params.is_autopaper) + scancount = 65536; + unsigned int reg0; + mb->read(0x00, reg0); + SMBCONFIG *smb_config = (SMBCONFIG *)®0; + smb_config->dpi_mode = m_config.g200params.dpi -1; + printf(" \n smb_config->dpi_mode =%d ", smb_config->dpi_mode); + mb->write(0x00, reg0); scannerinfo = getscannerinfo(); + imagehandler->Set_ratio(fpgaparam.HRatio, fpgaparam.VRatio); int spdmode = 0; if (scannerSp.count((SpeedMode)scannerinfo.speedmode) <= 0) { @@ -182,11 +420,10 @@ void Scanner::start_scan() #endif } else - { spdmode = scannerSp[(SpeedMode)scannerinfo.speedmode].motorSpeed; - } - mb->set_speed_mode(spdmode,1,1); - printf("\n set speedmode %d read speedmode %d", spdmode, mb->get_speed_mode()); + mb->set_speed_mode(spdmode); + printf("set speedmode %d read speedmode %d \n", spdmode, mb->get_speed_mode()); + // capturer->open(); imagehandler->resetimgstatus(); mb->clear_error(); fu_runscan.reset(new ThreadEx(&Scanner::runScan, this)); @@ -194,10 +431,11 @@ void Scanner::start_scan() void Scanner::stop_scan() { - mb->stop(); handstop = true; + printf("\n hand stop scan"); + mb->stop(); if (m_config.g200params.is_autopaper == 1) - mb->set_auto_paper(false); + mb->set_auto_paper(false, false); } int Scanner::count() @@ -209,6 +447,14 @@ int Scanner::mode() { return mb->os_mode(); } + +int Scanner::getimageprocedone() +{ + if (imagehandler.get()) + return imagehandler->done(); + return true; +} + int Scanner::getmbstatus() { mb->clear_error(); @@ -218,139 +464,552 @@ 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 (imagehandler && !imagehandler->done()); + // return (fu_runscan && fu_runscan->is_runing()) || (imagehandler && !imagehandler->done()); +} + +void Scanner::set_imagehandler(std::shared_ptr handler) +{ + imagehandler.reset(); + 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::testRunscan() +{ + for (;;) + { + if (done_scan) + break; + FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color); + capturer->open(m_config,fpgaparam); + int ch = 0; + int ixx = 0; + + // std::cout << "mod1:" << CV_8UC3 << " " << CV_8UC1 << std::endl; + StopWatch sw; + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + for (int i = 0; i < 150; i++) + { + capturer->snap(); + std::random_device rd; // obtain a random number from hardware + std::mt19937 gen(rd()); // seed the generator + std::uniform_int_distribution<> distr(150, 300); // define the range + std::this_thread::sleep_for(std::chrono::milliseconds(distr(gen))); + 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; + int dstHeight = capturer->getautosizeheight(); + static int scannum = 0; + void *data; + if (data = capturer->readFrame(5000)) + { + printf("\n+++++ readFrame:%fms+++++++++++\n", sw.elapsed_ms()); + if (imagehandler) + { + imagehandler->add_image(data, dstwith, dstHeight, capturer->color(), scannum,mfpgaversion); + } + } + else + { + printf("\n+++++ error readFrame:%fms+++++++++++\n", sw.elapsed_ms()); + } + } + capturer->close(); + } + imagehandler->add_scanevent({.From = STOPSCAN, 0}); +} -static int pickpapernum = 0; void Scanner::runScan() { - pickpapernum = 0; // system("sudo cpufreq-set -g performance"); system("echo performance > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor"); LOG_TRACE("+++++++scanner runinng+++++++++++++\n"); - mb->clear_error(); + + if(ExceptionCheck()) + { + printf("first page pick paper \n"); + startcapimage(true); + mb->pick_paper(); + { + done_scan = 0; + printf("set scancount %d\n", scancount); + mb->PutMsg(DisType::Dis_Scan, 0, ClearScreen::All); + mb->PutMsg(DisType::Dis_Scan_Page, mb->paper_counter(), ClearScreen::BOT); + + if (m_config.g200params.is_fixedpaper || m_config.g200params.paper != (uint)PaperSize::G400_AUTO) + fixedsizescan(); + else + autosizescan(); + savescannerinfo(scannerinfo); + while (!imagehandler->done()) + this_thread::sleep_for(chrono::milliseconds(10)); + done_scan = 0; + + if (wake.get()) + { + wake->resettime(); + wake->setsleepfalg(false); + } + system("sudo cpufreq-set -g ondemand"); + // system("sudo echo ondemand > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor"); + } + } + mb->SetKeyState(false); + m_capturereload.reset(new ThreadEx([&]{ + capturer->stop(); + capturer->close(); + capturer->reset(); })); + if ((((mb_error_code != 0) && (mb_error_code != 0xffffffff)) || imagehandler->getimgstatus().status != NO_error) && m_config.g200params.is_autopaper) + mb->set_auto_paper(false, false); + mb->startcapimage(false); + imagehandler->add_scanevent({.From = STOPSCAN, 0}); + ControlFeedMode(); + printf("-------scanner done-------\n"); +} + +bool Scanner::ExceptionCheck() +{ + bool ret = true; unsigned int val; - mb->set_double_inpect(m_config.g200params.double_feed_enbale); - mb->set_staple_inpect(m_config.g200params.stable_enbale); - // mb->set_paper_inspect(m_config.g200params.enable_sizecheck); - mb->set_auto_paper(m_config.g200params.is_autopaper);//m_config.g200params.is_autopaper - mb->set_screw_inpect(m_config.g200params.screw_detect_enable); - mb->set_screw_level(m_config.g200params.screw_detect_level); - mb->set_long_paper(m_config.g200params.paper); - //mb->set_cuospeed(41); - mb->start(); + mb->start(m_config); mb->read(0x01, val); if ((val & 0x700fe) > 0) { + ret = false; if ((val & 0x700fe) == 0x14) { imagehandler->add_scanevent({.From = MtBoard, .Code = 4}); LOG_TRACE("\nCover Open status"); imagehandler->add_scanevent({.From = STOPSCAN, 0}); - if (mb_error_code != 0 && m_config.g200params.is_autopaper) - mb->set_auto_paper(false); - return; } imagehandler->add_scanevent({.From = MtBoard, .Code = val & 0x700fe}); + if (m_config.g200params.is_autopaper) + { + imagehandler->add_scanevent({.From = STOPSCAN, 1}); + mb->set_auto_paper(false, false); + } + mb->errormsg(val & 0x1c003fa); printf("\n scan stop code =%d ", val & 0x700fe); } + +#ifdef G200 + StopWatch top_wh; + while (top_wh.elapsed_s() < 10) + { + if (is_ml_top || mb_error_code || handstop) + break; + this_thread::sleep_for(chrono::milliseconds(1)); + } + if (!is_ml_top || mb_error_code || handstop) + { + ret = false; + if (mb_error_code == 0 && handstop == 0) // 无其他异常时,发送升降台未到达指定位置异常 + { + imagehandler->add_scanevent({.From = MtBoard, 0x80000}); + if (m_config.g200params.is_autopaper) + mb->set_auto_paper(false, false); + } + if (mb_error_code && m_config.g200params.is_autopaper) + mb->set_auto_paper(false, false); + this_thread::sleep_for(chrono::milliseconds(20)); + imagehandler->add_scanevent({.From = STOPSCAN, 0}); + if (wake.get()) + { + wake->resettime(); + wake->setsleepfalg(false); + } + } + LOG_TRACE(string_format("waiting paper wait_arrival_top time = %0.2f ", top_wh.elapsed_ms())); +#endif + return ret; +} + +void Scanner::ControlFeedMode(){ + MotorboardParam::MBParam mbparam_tmp = MotorboardParam().GetParam(); + if (mbparam_tmp.automaticcontrolfeedmode) + { + printf("\n+++++++++ automaticcontrolfeedmode "); + MotorSessionInfo::MBTaskRecordInfo info_tmp{0}; + if (mb_error_code == 0) + info_tmp.NormalDone = true; + if (mb_error_code == 0x8) + info_tmp.FeedError = true; + if (mb_error_code == 0x10) + info_tmp.Jammed = true; + if (mb_error_code == 0x20) + info_tmp.DoubleFeed = true; + info_tmp.CurrentScaned = scannum; + FeedControl feedcontrol_tmp; + feedcontrol_tmp.AppendPattern(info_tmp); + switch (feedcontrol_tmp.GetPredictFeedMode()) + { + case FeedControl::FeedMode::FMode_Low: + setfeedmode(0); + break; + case FeedControl::FeedMode::FMode_Mid: + setfeedmode(1); + break; + case FeedControl::FeedMode::FMode_High: + setfeedmode(2); + break; + } + } +} + +bool Scanner::pickpaper() +{ + if (done_scan) + return false; + if (imagehandler) + { + while (imagehandler->is_limit()) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + // unsigned int reg2v; + // mb->read(0x02, reg2v); + // if (reg2v & 0x00010000) + // { //有纸 + printf("\n+++++++++pick paper "); + mb->pick_paper(); + startcapimage(true); + return true; + // } + // else + // { + // printf("\n+++++++++pick paper no paper"); + // return false; + // } +} + +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"); + 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 { -#ifdef G200 - if ((int)m_mbver > 0) - { - StopWatch top_wh; - while (top_wh.elapsed_s() < 10) - { - if (is_ml_top || mb_error_code || handstop) - break; - this_thread::sleep_for(chrono::milliseconds(1)); - } - if (!is_ml_top || mb_error_code || handstop) - { - if (mb_error_code == 0 && handstop == 0) // 无其他异常时,发送升降台未到达指定位置异常 - imagehandler->add_scanevent({.From = MtBoard, 0x80000}); - capturer->reset(); - this_thread::sleep_for(chrono::milliseconds(20)); - imagehandler->add_scanevent({.From = STOPSCAN, 0}); - return; - } - } - else - this_thread::sleep_for(chrono::milliseconds(2500)); -#endif - done_scan = 0; - if((int)m_mbver > 1) - scanpaperout(); - else - scanold(); + printf("LOST Image \n"); } - this_thread::sleep_for(chrono::milliseconds(1000)); + 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::settrayposition(int value) +{ + printf("\n Scanner settrayposition %d", value); + if (mb.get()) + { + uint val = 0; + mb->read(6, val); + auto tmp = *(SMB_FUNC *)&val; + tmp.param.lift_init_set = value; + mb->write(6, tmp.value); + printf("\n Scanner settrayposition mbvalue %d", tmp.value); + MotorboardParam().GetOrSetTrayPosition(false, value); + } +} + +void Scanner::setfeedmode(int value) +{ + printf("\n Scanner setfeedmode %d", value); + if (mb.get()) + { + uint val = 0; + mb->read(6, val); + auto tmp = *(SMB_FUNC *)&val; + switch (value) + { + case 0: + tmp.param.func_feed_low = 1; + tmp.param.func_feed_high = tmp.param.func_feed_mid = 0; + break; + case 1: + tmp.param.func_feed_mid = 1; + tmp.param.func_feed_high = tmp.param.func_feed_low = 0; + break; + case 2: + tmp.param.func_feed_high = 1; + tmp.param.func_feed_mid = tmp.param.func_feed_low = 0; + break; + default: + tmp.param.func_feed_mid = 1; + tmp.param.func_feed_high = tmp.param.func_feed_low = 0; + break; + } + mb->write(6, tmp.value); + printf("\n Scanner setfeedmode mbvalue %d", tmp.value); + MotorboardParam().GetOrSetFeedMode(false, value); + } +} +void Scanner::set_sleepstatus(bool off) +{ if (wake.get()) { - wake->resettime(); - wake->setsleepfalg(false); + if (off) + wake->power_on(); + else + wake->power_off(); } - imagehandler->add_scanevent({.From = STOPSCAN, 0}); - capturer->reset(); - if (mb_error_code != 0 && m_config.g200params.is_autopaper) - mb->set_auto_paper(false); - printf("\n-------scanner done-------\n"); } bool Scanner::getpaperon() { -#ifdef G200 + //#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, false); return val & 0x10000; } return 0; -#endif - return 1; + // #endif + // return 1; } -void Scanner::scanpaperout() -{ - StopWatch sw; - StopWatch swCap; - void *data = NULL; - int scannum = 0; - startcapimage(); - printf("first page pick paper \n"); +void Scanner::autosizescan() +{ + void *data = NULL; + scannum = 0; + StopWatch sw, swCap; for (;;) { LOG_TRACE("waiting paper"); - - if (!done_scan) // + if (!done_scan) //&& mb->wait_paper_in(10000) { - //LOG_TRACE(string_format("+++++paper on:%fms+++++++++++ ", swCap.elapsed_ms())); - if (mb->wait_paper_out(3000)) + printf("waiting paper"); + if (int ret = waitpaperout()) { - printf("wait_paper_out time =%f \n",sw.elapsed_ms()); - sw.reset(); - swCap.reset(); - if (data = capturer->readFrame(2000)) + printf("\n waitpaperout %d ", ret); { - printf("\n readFrame time =%f pickpapernum = %d",swCap.elapsed_ms(),pickpapernum++); - if (imagehandler) + if ((scancount <= (++scannum))) { - imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++,0x90001,CISVendor::DUNNAN_CIS_V0); - data = NULL; + done_scan = 1; + mb->stop(); + } + if (mb_error_code != 0) + { + printf("\n wait paperout mb_error_code break"); + if (!(m_cap.isuploadexceptionimage && (mb_error_code & 0x20) == 0x20)) + break; + else + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + } + if (ret == 3) + { + done_scan = true; + printf("\n wait paperout return 3 break"); + break; } - swCap.reset(); scannerinfo.RollerNum++; - LOG_TRACE(string_format("capture one=%fms", swCap.elapsed_ms())); + scannerinfo.TotalScanned++; + if (ret == 2) + { + mb->stop(); + done_scan = true; + imagehandler->add_scanevent({.From = MtBoard, .Code = 0x10000}); + this_thread::sleep_for(chrono::milliseconds(100)); + imagehandler->add_scanevent({.From = MtBoard, .Code = 0x40000}); + printf("\n paper with Hole stop "); + } + if (getcapimageflag()) + { + mb->stop(); + done_scan = true; + imagehandler->add_scanevent({.From = MtBoard, .Code = 0x10000}); + this_thread::sleep_for(chrono::milliseconds(100)); + imagehandler->add_scanevent({.From = MtBoard, .Code = 0x40000}); + break; + } + } + uint height = 0; + if (m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO) + { + capturer->regs()->read(0x14,height); + if(height < 1000 ) + std::this_thread::sleep_for(std::chrono::milliseconds((1000 - height)/70)); + int delaytime = m_config.g200params.dpi == 0x02 ? 100 : (m_config.g200params.dpi == 0x03 ? 250 : 30); + this_thread::sleep_for(chrono::milliseconds(delaytime)); //纸张过了 多采集几张 + height = capturer->getautosizeheight(); } else { - imagehandler->add_scanevent({.From = V4L2, .Code = 0}); - // LOG_TRACE("capture error"); - // done_scan = 1; - // capturer->stop(); - // mb->stop(); - LOG_TRACE("capture error Stop Scan"); - break; +#ifdef G200 + int delaytime = m_config.g200params.dpi == 0x02 ? 60 : (m_config.g200params.dpi == 0x03 ? 170 : 27); +#else + int delaytime = m_config.g200params.dpi == 0x02 ? 100 : (m_config.g200params.dpi == 0x03 ? 250 : 50); +#endif + this_thread::sleep_for(chrono::milliseconds(delaytime)); //纸张过了 多采集几张 + height = capturer->getautosizeheight(); + } + if (height) + { + if (!(m_cap.is_dogeardetection || m_cap.en_sizecheck)) + { + if (!pickpaper()) + done_scan = 1; + } + 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; + int dstHeight = height; + printf("\ndstwith =%d dstHeight = %d scancount %d", dstwith, dstHeight, scannum); + swCap.reset(); + if (data = capturer->readFrame(10000)) + { + printf("\n+++++ readFrame:%fms+++++++++++\n", sw.elapsed_ms()); + if (imagehandler) + { + imagehandler->add_image(data, dstwith, dstHeight, capturer->color(), scannum,mfpgaversion); + data = NULL; + } + if (m_cap.is_dogeardetection || m_cap.en_sizecheck) + { + if (imagehandler->getimgstatus().status != NO_error) + { + printf("\n+++++ status :%d ms+++++++++++\n", imagehandler->getimgstatus().status); + mb->stop(); + done_scan = 1; + switch (imagehandler->getimgstatus().status) + { + case Error_Status::Dog_error: + mb->PutMsg(DisType::Dis_Err_DogEar, 0, ClearScreen::All); + break; + case Error_Status::Size_error: + mb->PutMsg(DisType::Dis_Err_Size, 0, ClearScreen::All); + break; + default: + break; + } + } + else + { + if (!pickpaper()) + done_scan = 1; + } + } + printf("\n+++++ addimage:%fms+++++++++++\n", sw.elapsed_ms()); + LOG_TRACE(string_format("capture one=%fms", swCap.elapsed_ms())); + } + else + { + imagehandler->add_scanevent({.From = V4L2, .Code = 0}); + done_scan = true; + LOG_TRACE("capture error"); + printf("capture error \n"); + } } } else @@ -359,10 +1018,138 @@ void Scanner::scanpaperout() { uint value = 0; mb->read(0x2, value); - if (!(value & 0x20000))//bit 17 scandone + if (!(value & 0x20000)) // bit 17 scandone { + printf("mb 02 reg value =%d \n", value); done_scan = 1; LOG_TRACE("---------Time out-----"); + break; + } + else + { + mb->stop(); + done_scan = true; + imagehandler->add_scanevent({.From = MtBoard, .Code = 0x10000}); + printf("\n time out "); + break; + } + } + } + } + else + { + printf("\n done scan break"); + break; + } + } +} + +void Scanner::fixedsizescan() +{ + void *data = NULL; + scannum = 0; + StopWatch sw; + StopWatch swCap; + for (;;) + { + LOG_TRACE("waiting paper"); + if (!done_scan) //&& mb->wait_paper_in(10000) + { + // capturer->snap(); + printf("waiting paper...\n"); + int timedelay = m_config.g200params.dpi == 0x02 ? 25 : (m_config.g200params.dpi == 0x03 ? 35 : 15); + this_thread::sleep_for(chrono::milliseconds(timedelay)); //纸张过了 多采集几张 + if (mb->wait_paper_out(10000)) + { + if ((scancount <= (++scannum))) + { + done_scan = 1; + mb->stop(); + } + if (mb_error_code != 0) + { + printf("\n +++++ mb_error_code =%d ++++++", mb_error_code); + if (!(m_cap.isuploadexceptionimage && (mb_error_code & 0x20) == 0x20)) + break; + } + uint height; + if (m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO) + { + capturer->regs()->read(0x14,height); + if(height < 1000 ) + std::this_thread::sleep_for(std::chrono::milliseconds((1000 - height)/70)); + int delaytime = m_config.g200params.dpi == 0x02 ? 100 : (m_config.g200params.dpi == 0x03 ? 250 : 50); + this_thread::sleep_for(chrono::milliseconds(delaytime)); //纸张过了 多采集几张 + height = capturer->getautosizeheight(); + printf("\n+++++ getautosizeheights+++++++++++\n"); + } + else + { + height = capturer->height(); + printf("\n+++++ height+++++++++++\n"); + } + if (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; + // int dstHeight = height; + printf("\ndstwith =%d dstHeight = %d scancount %d", dstwith, dstHeight, scannum); + if (data = capturer->readFrame(10000)) + { + printf("\n+++++ readFrame:%fms+++++++++++\n", sw.elapsed_ms()); + if (imagehandler) + { + imagehandler->add_image(data, dstwith, dstHeight, capturer->color(), scannum,mfpgaversion); + data = NULL; + } + if (imagehandler->getimgstatus().status != NO_error) + { + printf("\n+++++ status :%d ms+++++++++++\n", imagehandler->getimgstatus().status); + mb->stop(); + done_scan = 1; + switch (imagehandler->getimgstatus().status) + { + case Error_Status::Dog_error: + mb->PutMsg(DisType::Dis_Err_DogEar, 0, ClearScreen::All); + break; + case Error_Status::Size_error: + mb->PutMsg(DisType::Dis_Err_Size, 0, ClearScreen::All); + break; + default: + break; + } + } + else + { + if (!pickpaper()) + done_scan = 1; + } + printf("\n+++++ addimage:%fms+++++++++++\n", sw.elapsed_ms()); + scannerinfo.RollerNum++; + scannerinfo.TotalScanned++; + } + else + { + imagehandler->add_scanevent({.From = V4L2, .Code = 0}); + done_scan = true; + LOG_TRACE("capture error"); + printf("capture error \n"); + } + } + } + else + { + if (!done_scan) + { + uint value = 0; + mb->read(0x2, value); + if (!(value & 0x20000)) // bit 17 scandone + { + printf("mb 02 reg value =%d \n", value); + done_scan = 1; + LOG_TRACE("---------Time out-----"); + break; } } } @@ -371,133 +1158,31 @@ void Scanner::scanpaperout() { break; } - if (imagehandler->getimgstatus().status != NO_error) - { - mb->stop(); - done_scan = 1; - capturer->stop(); - LOG_TRACE("imagehandler->getimgstatus().dogear_error "); - break; - } - if ((scancount <= scannum)) - { - done_scan = 1; - capturer->stop(); - this_thread::sleep_for(chrono::milliseconds(2000)); - mb->stop(); - break; - } - if (m_cap.resolution_dst >= 400 && papersMap[(PaperSize)m_config.g200params.paper].height <= 8100) - this_thread::sleep_for(chrono::milliseconds(3000)); - else if (m_cap.resolution_dst >= 400 && (papersMap[(PaperSize)m_config.g200params.paper].height > 8100 && papersMap[(PaperSize)m_config.g200params.paper].height <= 10800)) - this_thread::sleep_for(chrono::milliseconds(5000)); - else if (m_cap.resolution_dst >= 400 && papersMap[(PaperSize)m_config.g200params.paper].height > 10800) - this_thread::sleep_for(chrono::milliseconds(8000)); - startcapimage(); - mb->pick_paper(); - printf(" pick_paper time =%f \n", swCap.elapsed_ms()); - LOG_TRACE("pick_paper"); } - savescannerinfo(scannerinfo); - while (!imagehandler->done()) - this_thread::sleep_for(chrono::milliseconds(10)); - capturer->close(); - done_scan = 0; - system("sudo cpufreq-set -g ondemand"); - // system("sudo echo ondemand > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor"); - LOG_TRACE("-------scanner done-------\n"); } -void Scanner::scanold() +void Scanner::clean_paper_road() { - StopWatch sw; - StopWatch swCap; - void *data = NULL; - int scannum = 0; - for (;;) - { - LOG_TRACE("waiting paper"); - sw.reset(); - if (!done_scan && mb->wait_paper_in(1000)) - { - printf("wait_paper_in time =%f \n",swCap.elapsed_ms()); - //testGpio->setValue(Gpio::High); - LOG_TRACE(string_format("+++++paper on:%fms+++++++++++ ", swCap.elapsed_ms())); - capturer->snap(); - //testGpio->setValue(Gpio::Low); - swCap.reset(); - if (data = capturer->readFrame(2000)) - { - printf("readFrame time =%f \n",swCap.elapsed_ms()); - swCap.reset(); - if (imagehandler) - { - 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())); - printf("addimage time =%f \n",swCap.elapsed_ms()); - swCap.reset(); - scannerinfo.RollerNum++; - scannerinfo.TotalScanned++; - } - else - { - imagehandler->add_scanevent({.From = V4L2, .Code = 0}); - LOG_TRACE("capture error"); - } - swCap.reset(); - } - else if (done_scan) - { - break; - } - else - { - if (!done_scan) - { - uint value = 0; - mb->read(0x2, value); - if (!(value & 0x20000))//bit 17 scandone - { - printf("\n mb 02 reg value =%d ",value); - done_scan = 1; - LOG_TRACE("---------Time out-----"); - break; - } - } - } - if (imagehandler->getimgstatus().status != NO_error) - { - mb->stop(); - done_scan = 1; - capturer->stop(); - LOG_TRACE("imagehandler->getimgstatus().dogear_error "); - break; - } - if ((scancount <= scannum)) - { - done_scan = 1; - capturer->stop(); - this_thread::sleep_for(chrono::milliseconds(2000)); - mb->stop(); - break; - } - if(m_cap.resolution_dst>=400 && papersMap[(PaperSize)m_config.g200params.paper].height<=8100) - this_thread::sleep_for(chrono::milliseconds(3000)); - else if(m_cap.resolution_dst>=400 && (papersMap[(PaperSize)m_config.g200params.paper].height>8100&&papersMap[(PaperSize)m_config.g200params.paper].height<=10800)) - this_thread::sleep_for(chrono::milliseconds(5000)); - else if(m_cap.resolution_dst>=400 && papersMap[(PaperSize)m_config.g200params.paper].height>10800) - this_thread::sleep_for(chrono::milliseconds(8000)); - mb->pick_paper(); - swCap.reset(); - LOG_TRACE("pick_paper"); - } - savescannerinfo(scannerinfo); - while(!imagehandler->done()) - this_thread::sleep_for(chrono::milliseconds(10)); - capturer->close(); - done_scan = 0; - system("sudo cpufreq-set -g ondemand"); - //system("sudo echo ondemand > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor"); + if(mb.get()) + mb->clean_paper_road(); +} +int Scanner::waitpaperout() +{ + if (mb->wait_paper_out(10000)) //10秒内收到正常翻转信号或者异常时 返回 1 继续扫描 + return 1; + uint reg0,reg14; + reg0 = reg14 =0; + capturer->regs()->read(14, reg14); + capturer->regs()->read(0, reg0); + if(m_config.g200params.color) + reg14 *=3; + printf("\n wait paperout reg14 =%d reg0 =%d",reg14,reg0); + if ((reg14 & 0xffff) == 0) // 未收到异常与翻转信号 返回 0 退出扫描 + return 0; + // if(handstop && (capturer->regs()->read(14,val)&0xffff) > 0) + if (handstop) //pc手动停止时返回 3 退出扫描流程 不进行标位置回读和计数累加 + return 3; + if ((reg14 & 0xffff) == (reg0 & 0xffff)) + return mb_error_code == 0 ? 2 : 0; // 无异常有图像时 返回2 读取图像数据 防止丢图 + return 0; } \ No newline at end of file diff --git a/device/gxx-linux/scanner/scanner.h b/device/gxx-linux/scanner/scanner.h index 2afab49..6da31c1 100644 --- a/device/gxx-linux/scanner/scanner.h +++ b/device/gxx-linux/scanner/scanner.h @@ -1,31 +1,98 @@ #pragma once -#include "iscanner.h" +#include +#include +#include "BlockingQueue.h" +#include "fsmstate.h" +#include +#include "IScanner.h" +#include "wakeup.hpp" +#include "commondef.h" -enum MotorVersion : uint{ - Motor_old, - Motor_mltop, - Motor_paperout, -}; +class MotorBoard; +class ICapturer; +class IImageHandler; +class MotorController; +class CSizedetect; +class CImageApplyDogEarDetection; class Scanner : public IScanner { public: - Scanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake); + Scanner(std::shared_ptr capturer, std::shared_ptr mb, std::shared_ptr wake); virtual ~Scanner(); + virtual void try_scan(const std::string encodehexstr) override; + virtual void configparam(HGScanConfig config) override; virtual void start_scan() override; virtual void stop_scan() override; - virtual int count() override; + + virtual int count() override; virtual int mode() override; - virtual int getmbstatus() override; - virtual bool getpaperon() override; - virtual void runScan() override; + virtual void put(ScanEvent evt) override { sysEvent.Put(evt); } + virtual bool is_runscan() override; + virtual void set_imagehandler(std::shared_ptr handler = nullptr) override; + virtual void clear_error() override; + virtual bool paper_ready() override; + virtual bool get_keeplastpaper() override; + virtual void set_motorboardcallback(MotorBoardGlue glue) override; + virtual void set_imgprocparams(HGImgProcParms parmas) override; + virtual void test_autocorrect(int colormode) override; + virtual void test_cap(HGScanConfig config) override; + virtual bool set_hgimgconfig(GScanCap config) override; + virtual void add_scansever(HGIntInfo event) override; + virtual void set_sleeptime(int val) override; + virtual int get_sleeptime() override; + virtual void resettime() override; + virtual int get_sleepstatus() override; + virtual void set_sleepstatus(bool off) override; + virtual int getimageprocedone() override; + virtual void set_paprent(void *parent) override; + virtual bool getpaperon() override; + virtual int getmbstatus() override; + virtual std::string getmbversion() override; + virtual void setfeedmode(int value) override; + virtual void settrayposition(int value) override; + virtual void clean_paper_road() override; private: - void scanold(); - void scanpaperout(); + void runMessageLoop(); + void runScan(); + void testRunscan(); + void preFeed(); + void startcapimage(bool value); + bool getcapimageflag(); + bool pickpaper(); + void autosizescan(); + void fixedsizescan(); + int waitpaperout(); + void ControlFeedMode(); + bool ExceptionCheck(); + ImgStatus ImgDetect(); + std::thread threadRunMessageLoop; + volatile bool bMsgLoop = true; + BlockingQueue sysEvent; + + std::shared_ptr m_dog; + std::shared_ptr m_sizedetect; + + std::shared_ptr mb; + std::shared_ptr capturer; + std::shared_ptr wake; + + std::shared_ptr fu_runscan; + std::shared_ptr imagehandler; + std::shared_ptr m_motorcontrol; + + std::shared_ptr m_capturereload; + std::function m_mtcallback; volatile int done_scan = 0; volatile bool is_ml_top = 0; volatile bool handstop = 0; - volatile int mb_error_code = 0; - MotorVersion m_mbver; - + volatile int scannum = 0; + int scancount = 0; + volatile unsigned int mb_error_code; + HGScanConfig m_config; + GScanCap m_cap; + ScannerNativeParam scannerinfo; + void *m_parent; + std::string mbversion; + unsigned int mfpgaversion; }; diff --git a/device/gxx-linux/scanner/scannero300.cpp b/device/gxx-linux/scanner/scannero300.cpp deleted file mode 100644 index e4849ee..0000000 --- a/device/gxx-linux/scanner/scannero300.cpp +++ /dev/null @@ -1,293 +0,0 @@ -#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 deleted file mode 100644 index 62a2615..0000000 --- a/device/gxx-linux/scanner/scannero300.h +++ /dev/null @@ -1,23 +0,0 @@ -#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 0c813d8..1abe04b 100644 --- a/device/gxx-linux/scanner/scannerregs.cpp +++ b/device/gxx-linux/scanner/scannerregs.cpp @@ -1,7 +1,9 @@ #include "scannerregs.h" #include #include -#include "iscanner.h" +#include +#include "IScanner.h" +#include "scanner.h" #include "usbimageprocqueue.h" #include "filetools.h" #include "stringex.hpp" @@ -10,11 +12,10 @@ #include "memoryex.h" #include "jsonconfig.h" #include "CorrectParam.h" +#include "MotorboardParam.h" #include "hgutils.h" -#include "MotorConfig.h" -#include "dailex.hpp" -#include "deviceconfig.h" #include "base64.hpp" +#include "deviceconfig.h" unsigned long getfilesize(const char *filename) { @@ -89,6 +90,7 @@ ScannerRegAccess::ScannerRegAccess(std::shared_ptr scanner, std::share this->m_upstautus = Start_updata; this->scanner->set_paprent(this); file_pos = 0; + m_token = "null"; } ScannerRegAccess::~ScannerRegAccess() @@ -144,10 +146,6 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) return true; case SR_IM_TYPE: return true; - case SR_NOTIFY_SLEEP: - if(scanner->get_sleepstatus() == 0) - scanner->set_sleepstatus(true); - return true; case SR_IM_TX: { // if (val != 1 && (transmit->is_writing() || usbimages->empty())) @@ -166,11 +164,24 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) } return true; } + case SR_NOTIFY_SLEEP: + if(scanner->get_sleepstatus() == 0) + scanner->set_sleepstatus(true); + return true; + case SR_SET_FEEDMODE: + if(val <3 && val >=0) + scanner->setfeedmode(val); + return true; + case SR_SET_TRAYPOSITION: + if(val <3 && val >=0) + scanner->settrayposition(val); + return true; case SR_IM_POP: usbimages->pop(); return true; case SR_IM_ABORT: transmit->cannel(); + printf("\n SR_IM_ABORT "); return true; case SR_CONFIG_SCAN_PARAM: scanner->configparam(*((HGScanConfig *)&val)); @@ -191,6 +202,8 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) cap.resolution_dst = scan_dpi; cap.resolution_native = 200; cap.scannum = scan_cnt; + cap.pixtype = 0; + usbimages->set_dpi(scan_dpi, scan_dpi); printf("DPI: %d, Count: %d\n", scan_dpi, scan_cnt); #else std::vector data(val); @@ -277,7 +290,7 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) } case SR_UPDATA_START: { - scanner->set_sleepstatus(false); + //scanner->set_sleepstatus(false); //安路电机板更新时需要电机板不断�? int currlenght = 0; std::vector buff; std::fstream fd; @@ -328,7 +341,7 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) return true; } case SR_REBOOT: - { + { if(val >0) system("reboot loader"); else @@ -340,6 +353,14 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) system("poweroff"); return true; } + case SR_SET_STARTBACKUP: + { + printf("start Back up system\n"); + system("touch /etc/back_status"); + system("echo 0 > /etc/back_status"); + system("/etc/hgbackup_auto.sh &"); + return true; + } case SR_SET_H_RATIO: case SR_SET_V_RATIO: case SR_SET_H_200_RATIO: @@ -411,20 +432,11 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) case SR_SET_SPEEDMODE: { auto info = getscannerinfo(); - if(scannerSp.find((SpeedMode)info.speedmode)== scannerSp.end()) - return true; - printf("\nSR_SET_SPEEDMODE %d",val); #ifdef G200 - if(val == 100 || val == 110 || val == 120 || val == 130) - info.speedmode= val; -#elif defined G100 - if(val == 70 || val == 80 || val == 90 || val == 110) - info.speedmode = val; -#elif defined G400 - if(val == 40 || val == 50 || val == 60 || val == 70 ||val == 80) + if (val == 100 || val == 140 || val == 110 || val == 120 || val == 130) info.speedmode = val; #else - if(val == 40 || val == 50 || val == 60 || val == 70) + if (val == 100 || val == 70 || val == 80 || val == 90 || val == 110) info.speedmode = val; #endif setcameraparmSp(val); @@ -522,6 +534,26 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) file_pos = val; return true; } + case SR_SET_AUTOMATICCONTROLFEEDMODE_ENABLE: + { + if(val == 0) + MotorboardParam().GetOrSetEnableAutomaticControlFeedMode(false,0); + else + MotorboardParam().GetOrSetEnableAutomaticControlFeedMode(false,1); + return true; + } + case SR_SET_AUTOMATICCONTROLFEEDMODE_THRESHOLD: + { + float fx = *((float *)&val); + printf("\n SR_SET_AUTOMATICCONTROLFEEDMODE_THRESHOLD %f",fx); + if(fx >0 && fx < 1) + { + auto param_tmp = MotorboardParam().GetParam(); + param_tmp.automaticcontrolfeedmode_threshold = fx; + MotorboardParam().SaveParam(param_tmp); + } + return true; + } case SR_SET_LOCK_STATES: { printf("\n SR_SET_LOCK_STATES %d",val); @@ -564,6 +596,9 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) token.resize(val); recieve->read_bulk(&token[0],val); m_token = token; + printf("\n token = "); + for(int i =0;iwrite_bulk(&tmp[0],val); return true; } - case SR_SET_STARTBACKUP: - { - printf("start Back up system\n"); - system("touch /etc/back_status"); - system("echo 0 > /etc/back_status"); - system("/etc/hgbackup_auto.sh &"); - return true; - } case SR_CLEAN_PAPER_ROAD: - { - if(!scanner->is_runscan()) - scanner->clean_paper_road(); + scanner->clean_paper_road(); return true; - } - case SR_EXECUTE_CMD: { std::string cmd; @@ -623,7 +646,7 @@ bool ScannerRegAccess::read(unsigned int addr, unsigned int &val) switch (addr) { case SR_STATUS: - val = scanner->is_runscan() | ((!usbimages->empty()) << 1) | scanner->paper_ready() << 2; + val = scanner->is_runscan() | ((!usbimages->empty()) << 1) | scanner->paper_ready() << 2;//1/0 (1/0 << 1 | 1/0<< 2) LOG_TRACE(string_format("run status:%d", val)); return true; case SR_SCAN_COUNT: @@ -683,6 +706,12 @@ bool ScannerRegAccess::read(unsigned int addr, unsigned int &val) } return true; } + case SR_GET_BACKUPSTATUS: + { + std::ifstream i("/etc/back_status"); + i>> val; + return true; + } case SR_UPDATA_REBOOT: { if (m_upstautus == MD5_Rboot) @@ -845,6 +874,27 @@ bool ScannerRegAccess::read(unsigned int addr, unsigned int &val) val = file_pos; return true; } + case SR_GET_FEEDMODE: + { + val = MotorboardParam().GetOrSetFeedMode(true,0); + return true; + } + case SR_GET_TRAYPOSITION: + { + val = MotorboardParam().GetOrSetTrayPosition(true,0); + return true; + } + case SR_GET_AUTOMATICCONTROLFEEDMODE_ENABLE: + { + val = MotorboardParam().GetOrSetEnableAutomaticControlFeedMode(true,0); + return true; + } + case SR_GET_AUTOMATICCONTROLFEEDMODE_THRESHOLD: + { + float tmp = MotorboardParam().GetParam().automaticcontrolfeedmode_threshold; + val = *((unsigned int *)&tmp); + return true; + } case SR_GET_LOCK_STATES: { val = DeviceConfig().GetParam().is_lock; @@ -857,12 +907,6 @@ bool ScannerRegAccess::read(unsigned int addr, unsigned int &val) val = tmp.length(); return true; } - case SR_GET_BACKUPSTATUS: - { - std::ifstream i("/etc/back_status"); - i>> val; - return true; - } case SR_EXECUTE_CMD_OUT_LENGHT: { val = cmd_out.size(); @@ -879,9 +923,9 @@ bool ScannerRegAccess::cmd(const unsigned int val) switch (val) { case SC_START: - if(scanner->check_scan(m_token)) - scanner->start_scan(); + scanner->try_scan(m_token); m_token = "null"; + //scanner->start_scan(); return true; case SC_STOP: scanner->stop_scan(); @@ -1007,8 +1051,6 @@ void ScannerRegAccess::set_image_callback(void(*cb)(MemoryPtr, bool, void*), voi void ScannerRegAccess::setcameraparmSp(int speedmode){ if(cameraparmSp.find(SpeedMode(speedmode)) == cameraparmSp.end()) return ; - printf("\nSetcameraparmSp %d",speedmode); -#if defined (G100) ||defined (G200) CorrectParam cparam; for(int i=1;i<4;i++) { @@ -1031,44 +1073,4 @@ void ScannerRegAccess::setcameraparmSp(int speedmode){ cparam.SaveCorrectParam(param); } } -#elif defined (G300) || defined (G400) - MotorConfig().reset_json(); - MotorConfig::MTBDType m_mttype; - int index = 0; - if(Dail().GetValue().dails.in_voltage4 != 0) - index = 60; - switch (speedmode) - { - case 40: index += 0 ;break; - case 50: index += 6 ;break; - case 60: index += 12 ;break; - case 70: index += 18 ;break; - case 80: index += 24 ;break; - default: - break; - } - CorrectParam cparam; - for(int i=1;i<4;i++) - { - for(int j =0; j<2;j++) - { - auto param = cparam.GetFpgaparam(i,j); - if((j==1)&& (i==1)) - param.Sp = m_motor_params[index+1].sp; - if((j==0)&& (i==1)) - param.Sp = m_motor_params[index].sp; - if((j==1)&& (i==2)) - param.Sp = m_motor_params[index+3].sp; - if((j==0)&& (i==2)) - param.Sp = m_motor_params[index+2].sp; - if((j==1)&& (i==3)) - param.Sp = m_motor_params[index+5].sp; - if((j==0)&& (i==3)) - param.Sp = m_motor_params[index+4].sp; - printf("\n param.Sp = %d", param.Sp); - cparam.SaveCorrectParam(param); - } - } -#endif - -} +} \ No newline at end of file diff --git a/device/gxx-linux/scanner/scannerregs.h b/device/gxx-linux/scanner/scannerregs.h index a6da03d..dca0f65 100644 --- a/device/gxx-linux/scanner/scannerregs.h +++ b/device/gxx-linux/scanner/scannerregs.h @@ -29,9 +29,9 @@ private: bool cmd(const unsigned int val); bool procscannerinfo(unsigned int addr,unsigned int& value); Updata_Stautus m_upstautus; + std::string cmd_out; std::string jsonpath; std::string m_token; - std::string cmd_out; volatile std::uint32_t file_pos; std::shared_ptr scanner; std::shared_ptr usbimages; diff --git a/device/gxx-linux/scanner/wakeup.hpp b/device/gxx-linux/scanner/wakeup.hpp index ee94a59..8a89227 100644 --- a/device/gxx-linux/scanner/wakeup.hpp +++ b/device/gxx-linux/scanner/wakeup.hpp @@ -148,7 +148,6 @@ private: } 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"); @@ -169,6 +168,8 @@ private: printf("error sleep index.\n"); } } + + } } } diff --git a/device/gxx-linux/scanner/xmake.lua b/device/gxx-linux/scanner/xmake.lua index f33dd5c..98adcf0 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("ssl","crypto") -- add_links("turbojpeg") + add_links("ssl","crypto") 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/scannerinfo.json b/device/gxx-linux/scannerinfo.json deleted file mode 100644 index 1a6d878..0000000 --- a/device/gxx-linux/scannerinfo.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "ColorSp": 636, - "DoubleNum": 0, - "FeedError": 0, - "FlatClrMaxBrt": 180, - "FlatGrayMaxBrt": 180, - "GraySp": 1909, - "HRatio": 1065353216, - "JamInNum": 0, - "PID": 569, - "RollerNum": 3052, - "ScanTimes": 0, - "ScannerToken": "abcdefghijklmnopqrstuvwxyz012345", - "SerialNum": "G2396021071101", - "Sleeptime": -1, - "SpeedMode": 100, - "TotalScanned": 3052, - "VID": 12402, - "VRatio": 1065353216 -} diff --git a/device/gxx-linux/scanservice/main.cpp b/device/gxx-linux/scanservice/main.cpp index d5f1d85..6f8cdd4 100644 --- a/device/gxx-linux/scanservice/main.cpp +++ b/device/gxx-linux/scanservice/main.cpp @@ -1,239 +1,3 @@ -// #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 @@ -246,13 +10,11 @@ #include #include #include "filetools.h" +#include "stringex.hpp" #include #include "usbservice.h" +#include "ICapturer.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" @@ -265,9 +27,7 @@ #include "applog.h" #include "jsonconfig.h" #include "wakeup.hpp" -#include "Led.h" -#include "dailex.hpp" - +#include "StopWatch.h" using namespace std; #define MY_PID_FILE "/tmp/scanservice_pid" #define BUF_LEN_FOR_PID 64 @@ -421,7 +181,6 @@ static void sigHandler(int sig) int main() { - if (-1 == init_pid_file()) { exit(-1); @@ -438,59 +197,41 @@ int main() { exit(-1); } - //auto deviceinfo = jsonconfig().getdeviceinfo(); auto wake = std::shared_ptr(new WakeUp()); - //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]{ + auto cap = std::shared_ptr(new MonoCapturer()); + auto mt = std::shared_ptr(new MotorBoard(wake)); + wake->setinitcallback([&mt,&cap]{ 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->reset(); + mt->init_statecontrol(); + },[&mt,&cap]{ cap->Fpga_regsAccess_reset(false); - mt->LedControlOption(HG_LedOption::HG_GREEN_ON,0); - mt->GetOrSetSleepFlag(false,true); - + mt->release_statecontrol(); }); if(wake->get_status() == 0) { cap->Fpga_regsAccess_reset(false); - mt->LedControlOption(HG_LedOption::HG_GREEN_ON,0); - mt->GetOrSetSleepFlag(false,true); + 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("\nUSB Connect\n"); + }else + { + scanner->stop_scan(); + mt->release_statecontrol(); + 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)); diff --git a/device/gxx-linux/scanservice/xmake.lua b/device/gxx-linux/scanservice/xmake.lua index 0c7f929..cb20cc0 100644 --- a/device/gxx-linux/scanservice/xmake.lua +++ b/device/gxx-linux/scanservice/xmake.lua @@ -1,7 +1,10 @@ add_rules("mode.debug", "mode.release") + target("scanservice") set_kind("binary") add_files("*.cpp") add_deps("gusb", "applog") + --add_rules("utils.bin2c",{linewidth = 32,extension = {".bin"}}) + --add_files("table.bin") add_packages("common") add_deps("capimage", "motorboard", "gscanner") \ No newline at end of file diff --git a/device/gxx-linux/service/main.cpp b/device/gxx-linux/service/main.cpp index 7994b53..7818e21 100644 --- a/device/gxx-linux/service/main.cpp +++ b/device/gxx-linux/service/main.cpp @@ -25,7 +25,7 @@ int menu() { int main() { bool exit = false; - std::shared_ptr motorboard(new MotorBoard()); + std::shared_ptr motorboard(new MotorBoard(nullptr)); std::shared_ptr capturer(new Capturer()); std::shared_ptr scanner(new Scanner(capturer, motorboard,nullptr)); std::shared_ptr scannerRegs(new ScannerRegAccess(scanner)); diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/.DevUtil.o.d b/device/gxx-linux/small_lcd/app_spi_lcd/.DevUtil.o.d new file mode 100644 index 0000000..a6fd32b --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/.DevUtil.o.d @@ -0,0 +1,170 @@ +DevUtil.o: DevUtil.cpp /usr/include/stdc-predef.h DevUtil.h \ + /usr/include/c++/8/string \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++config.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/os_defines.h \ + /usr/include/features.h /usr/include/aarch64-linux-gnu/sys/cdefs.h \ + /usr/include/aarch64-linux-gnu/bits/wordsize.h \ + /usr/include/aarch64-linux-gnu/bits/long-double.h \ + /usr/include/aarch64-linux-gnu/gnu/stubs.h \ + /usr/include/aarch64-linux-gnu/gnu/stubs-lp64.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/cpu_defines.h \ + /usr/include/c++/8/bits/stringfwd.h /usr/include/c++/8/bits/memoryfwd.h \ + /usr/include/c++/8/bits/char_traits.h \ + /usr/include/c++/8/bits/stl_algobase.h \ + /usr/include/c++/8/bits/functexcept.h \ + /usr/include/c++/8/bits/exception_defines.h \ + /usr/include/c++/8/bits/cpp_type_traits.h \ + /usr/include/c++/8/ext/type_traits.h \ + /usr/include/c++/8/ext/numeric_traits.h \ + /usr/include/c++/8/bits/stl_pair.h /usr/include/c++/8/bits/move.h \ + /usr/include/c++/8/bits/concept_check.h /usr/include/c++/8/type_traits \ + /usr/include/c++/8/bits/stl_iterator_base_types.h \ + /usr/include/c++/8/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/8/debug/assertions.h \ + /usr/include/c++/8/bits/stl_iterator.h \ + /usr/include/c++/8/bits/ptr_traits.h /usr/include/c++/8/debug/debug.h \ + /usr/include/c++/8/bits/predefined_ops.h \ + /usr/include/c++/8/bits/postypes.h /usr/include/c++/8/cwchar \ + /usr/include/wchar.h \ + /usr/include/aarch64-linux-gnu/bits/libc-header-start.h \ + /usr/include/aarch64-linux-gnu/bits/floatn.h \ + /usr/include/aarch64-linux-gnu/bits/floatn-common.h \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stddef.h \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stdarg.h \ + /usr/include/aarch64-linux-gnu/bits/wchar.h \ + /usr/include/aarch64-linux-gnu/bits/types/wint_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/locale_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/c++/8/cstdint \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stdint.h /usr/include/stdint.h \ + /usr/include/aarch64-linux-gnu/bits/types.h \ + /usr/include/aarch64-linux-gnu/bits/typesizes.h \ + /usr/include/aarch64-linux-gnu/bits/stdint-intn.h \ + /usr/include/aarch64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/c++/8/bits/allocator.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++allocator.h \ + /usr/include/c++/8/ext/new_allocator.h /usr/include/c++/8/new \ + /usr/include/c++/8/exception /usr/include/c++/8/bits/exception.h \ + /usr/include/c++/8/bits/exception_ptr.h \ + /usr/include/c++/8/bits/cxxabi_init_exception.h \ + /usr/include/c++/8/typeinfo /usr/include/c++/8/bits/hash_bytes.h \ + /usr/include/c++/8/bits/nested_exception.h \ + /usr/include/c++/8/bits/localefwd.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++locale.h \ + /usr/include/c++/8/clocale /usr/include/locale.h \ + /usr/include/aarch64-linux-gnu/bits/locale.h /usr/include/c++/8/iosfwd \ + /usr/include/c++/8/cctype /usr/include/ctype.h /usr/include/endian.h \ + /usr/include/aarch64-linux-gnu/bits/endian.h \ + /usr/include/aarch64-linux-gnu/bits/byteswap.h \ + /usr/include/aarch64-linux-gnu/bits/uintn-identity.h \ + /usr/include/c++/8/bits/ostream_insert.h \ + /usr/include/c++/8/bits/cxxabi_forced.h \ + /usr/include/c++/8/bits/stl_function.h \ + /usr/include/c++/8/backward/binders.h \ + /usr/include/c++/8/bits/range_access.h \ + /usr/include/c++/8/initializer_list \ + /usr/include/c++/8/bits/basic_string.h \ + /usr/include/c++/8/ext/atomicity.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/gthr.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/aarch64-linux-gnu/bits/types/time_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/aarch64-linux-gnu/bits/sched.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/aarch64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/aarch64-linux-gnu/bits/time.h \ + /usr/include/aarch64-linux-gnu/bits/timex.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/aarch64-linux-gnu/bits/types/clock_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/aarch64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/timer_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/aarch64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/aarch64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/aarch64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/aarch64-linux-gnu/bits/setjmp.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/atomic_word.h \ + /usr/include/c++/8/ext/alloc_traits.h \ + /usr/include/c++/8/bits/alloc_traits.h \ + /usr/include/c++/8/ext/string_conversions.h /usr/include/c++/8/cstdlib \ + /usr/include/stdlib.h /usr/include/aarch64-linux-gnu/bits/waitflags.h \ + /usr/include/aarch64-linux-gnu/bits/waitstatus.h \ + /usr/include/aarch64-linux-gnu/sys/types.h \ + /usr/include/aarch64-linux-gnu/sys/select.h \ + /usr/include/aarch64-linux-gnu/bits/select.h \ + /usr/include/aarch64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/alloca.h /usr/include/aarch64-linux-gnu/bits/stdlib-float.h \ + /usr/include/c++/8/bits/std_abs.h /usr/include/c++/8/cstdio \ + /usr/include/stdio.h \ + /usr/include/aarch64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/aarch64-linux-gnu/bits/stdio_lim.h \ + /usr/include/aarch64-linux-gnu/bits/sys_errlist.h \ + /usr/include/c++/8/cerrno /usr/include/errno.h \ + /usr/include/aarch64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/aarch64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/aarch64-linux-gnu/bits/types/error_t.h \ + /usr/include/c++/8/bits/functional_hash.h \ + /usr/include/c++/8/bits/basic_string.tcc /usr/include/c++/8/fstream \ + /usr/include/c++/8/istream /usr/include/c++/8/ios \ + /usr/include/c++/8/bits/ios_base.h \ + /usr/include/c++/8/bits/locale_classes.h \ + /usr/include/c++/8/bits/locale_classes.tcc \ + /usr/include/c++/8/system_error \ + /usr/include/aarch64-linux-gnu/c++/8/bits/error_constants.h \ + /usr/include/c++/8/stdexcept /usr/include/c++/8/streambuf \ + /usr/include/c++/8/bits/streambuf.tcc \ + /usr/include/c++/8/bits/basic_ios.h \ + /usr/include/c++/8/bits/locale_facets.h /usr/include/c++/8/cwctype \ + /usr/include/wctype.h /usr/include/aarch64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/ctype_base.h \ + /usr/include/c++/8/bits/streambuf_iterator.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/ctype_inline.h \ + /usr/include/c++/8/bits/locale_facets.tcc \ + /usr/include/c++/8/bits/basic_ios.tcc /usr/include/c++/8/ostream \ + /usr/include/c++/8/bits/ostream.tcc /usr/include/c++/8/bits/istream.tcc \ + /usr/include/c++/8/bits/codecvt.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/basic_file.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++io.h \ + /usr/include/c++/8/bits/fstream.tcc /usr/include/c++/8/memory \ + /usr/include/c++/8/bits/stl_construct.h \ + /usr/include/c++/8/bits/stl_uninitialized.h \ + /usr/include/c++/8/bits/stl_tempbuf.h \ + /usr/include/c++/8/bits/stl_raw_storage_iter.h \ + /usr/include/c++/8/ext/concurrence.h \ + /usr/include/c++/8/bits/uses_allocator.h \ + /usr/include/c++/8/bits/unique_ptr.h /usr/include/c++/8/utility \ + /usr/include/c++/8/bits/stl_relops.h /usr/include/c++/8/tuple \ + /usr/include/c++/8/array /usr/include/c++/8/bits/invoke.h \ + /usr/include/c++/8/bits/shared_ptr.h \ + /usr/include/c++/8/bits/shared_ptr_base.h \ + /usr/include/c++/8/bits/allocated_ptr.h \ + /usr/include/c++/8/bits/refwrap.h \ + /usr/include/c++/8/ext/aligned_buffer.h \ + /usr/include/c++/8/bits/shared_ptr_atomic.h \ + /usr/include/c++/8/bits/atomic_base.h \ + /usr/include/c++/8/bits/atomic_lockfree_defines.h \ + /usr/include/c++/8/backward/auto_ptr.h /usr/include/unistd.h \ + /usr/include/aarch64-linux-gnu/bits/posix_opt.h \ + /usr/include/aarch64-linux-gnu/bits/environments.h \ + /usr/include/aarch64-linux-gnu/bits/confname.h \ + /usr/include/aarch64-linux-gnu/bits/getopt_posix.h \ + /usr/include/aarch64-linux-gnu/bits/getopt_core.h \ + /usr/include/aarch64-linux-gnu/sys/stat.h \ + /usr/include/aarch64-linux-gnu/bits/stat.h \ + /usr/include/aarch64-linux-gnu/bits/statx.h \ + /usr/include/aarch64-linux-gnu/sys/time.h /usr/include/c++/8/stdlib.h \ + /usr/include/fcntl.h /usr/include/aarch64-linux-gnu/bits/fcntl.h \ + /usr/include/aarch64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/linux/falloc.h diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/.Gpio.o.d b/device/gxx-linux/small_lcd/app_spi_lcd/.Gpio.o.d new file mode 100644 index 0000000..e295f64 --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/.Gpio.o.d @@ -0,0 +1,169 @@ +Gpio.o: Gpio.cpp /usr/include/stdc-predef.h Gpio.h \ + /usr/include/c++/8/string \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++config.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/os_defines.h \ + /usr/include/features.h /usr/include/aarch64-linux-gnu/sys/cdefs.h \ + /usr/include/aarch64-linux-gnu/bits/wordsize.h \ + /usr/include/aarch64-linux-gnu/bits/long-double.h \ + /usr/include/aarch64-linux-gnu/gnu/stubs.h \ + /usr/include/aarch64-linux-gnu/gnu/stubs-lp64.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/cpu_defines.h \ + /usr/include/c++/8/bits/stringfwd.h /usr/include/c++/8/bits/memoryfwd.h \ + /usr/include/c++/8/bits/char_traits.h \ + /usr/include/c++/8/bits/stl_algobase.h \ + /usr/include/c++/8/bits/functexcept.h \ + /usr/include/c++/8/bits/exception_defines.h \ + /usr/include/c++/8/bits/cpp_type_traits.h \ + /usr/include/c++/8/ext/type_traits.h \ + /usr/include/c++/8/ext/numeric_traits.h \ + /usr/include/c++/8/bits/stl_pair.h /usr/include/c++/8/bits/move.h \ + /usr/include/c++/8/bits/concept_check.h /usr/include/c++/8/type_traits \ + /usr/include/c++/8/bits/stl_iterator_base_types.h \ + /usr/include/c++/8/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/8/debug/assertions.h \ + /usr/include/c++/8/bits/stl_iterator.h \ + /usr/include/c++/8/bits/ptr_traits.h /usr/include/c++/8/debug/debug.h \ + /usr/include/c++/8/bits/predefined_ops.h \ + /usr/include/c++/8/bits/postypes.h /usr/include/c++/8/cwchar \ + /usr/include/wchar.h \ + /usr/include/aarch64-linux-gnu/bits/libc-header-start.h \ + /usr/include/aarch64-linux-gnu/bits/floatn.h \ + /usr/include/aarch64-linux-gnu/bits/floatn-common.h \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stddef.h \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stdarg.h \ + /usr/include/aarch64-linux-gnu/bits/wchar.h \ + /usr/include/aarch64-linux-gnu/bits/types/wint_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/locale_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/c++/8/cstdint \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stdint.h /usr/include/stdint.h \ + /usr/include/aarch64-linux-gnu/bits/types.h \ + /usr/include/aarch64-linux-gnu/bits/typesizes.h \ + /usr/include/aarch64-linux-gnu/bits/stdint-intn.h \ + /usr/include/aarch64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/c++/8/bits/allocator.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++allocator.h \ + /usr/include/c++/8/ext/new_allocator.h /usr/include/c++/8/new \ + /usr/include/c++/8/exception /usr/include/c++/8/bits/exception.h \ + /usr/include/c++/8/bits/exception_ptr.h \ + /usr/include/c++/8/bits/cxxabi_init_exception.h \ + /usr/include/c++/8/typeinfo /usr/include/c++/8/bits/hash_bytes.h \ + /usr/include/c++/8/bits/nested_exception.h \ + /usr/include/c++/8/bits/localefwd.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++locale.h \ + /usr/include/c++/8/clocale /usr/include/locale.h \ + /usr/include/aarch64-linux-gnu/bits/locale.h /usr/include/c++/8/iosfwd \ + /usr/include/c++/8/cctype /usr/include/ctype.h /usr/include/endian.h \ + /usr/include/aarch64-linux-gnu/bits/endian.h \ + /usr/include/aarch64-linux-gnu/bits/byteswap.h \ + /usr/include/aarch64-linux-gnu/bits/uintn-identity.h \ + /usr/include/c++/8/bits/ostream_insert.h \ + /usr/include/c++/8/bits/cxxabi_forced.h \ + /usr/include/c++/8/bits/stl_function.h \ + /usr/include/c++/8/backward/binders.h \ + /usr/include/c++/8/bits/range_access.h \ + /usr/include/c++/8/initializer_list \ + /usr/include/c++/8/bits/basic_string.h \ + /usr/include/c++/8/ext/atomicity.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/gthr.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/aarch64-linux-gnu/bits/types/time_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/aarch64-linux-gnu/bits/sched.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/aarch64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/aarch64-linux-gnu/bits/time.h \ + /usr/include/aarch64-linux-gnu/bits/timex.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/aarch64-linux-gnu/bits/types/clock_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/aarch64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/timer_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/aarch64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/aarch64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/aarch64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/aarch64-linux-gnu/bits/setjmp.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/atomic_word.h \ + /usr/include/c++/8/ext/alloc_traits.h \ + /usr/include/c++/8/bits/alloc_traits.h \ + /usr/include/c++/8/ext/string_conversions.h /usr/include/c++/8/cstdlib \ + /usr/include/stdlib.h /usr/include/aarch64-linux-gnu/bits/waitflags.h \ + /usr/include/aarch64-linux-gnu/bits/waitstatus.h \ + /usr/include/aarch64-linux-gnu/sys/types.h \ + /usr/include/aarch64-linux-gnu/sys/select.h \ + /usr/include/aarch64-linux-gnu/bits/select.h \ + /usr/include/aarch64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/alloca.h /usr/include/aarch64-linux-gnu/bits/stdlib-float.h \ + /usr/include/c++/8/bits/std_abs.h /usr/include/c++/8/cstdio \ + /usr/include/stdio.h \ + /usr/include/aarch64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/aarch64-linux-gnu/bits/stdio_lim.h \ + /usr/include/aarch64-linux-gnu/bits/sys_errlist.h \ + /usr/include/c++/8/cerrno /usr/include/errno.h \ + /usr/include/aarch64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/aarch64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/aarch64-linux-gnu/bits/types/error_t.h \ + /usr/include/c++/8/bits/functional_hash.h \ + /usr/include/c++/8/bits/basic_string.tcc DevUtil.h \ + /usr/include/c++/8/fstream /usr/include/c++/8/istream \ + /usr/include/c++/8/ios /usr/include/c++/8/bits/ios_base.h \ + /usr/include/c++/8/bits/locale_classes.h \ + /usr/include/c++/8/bits/locale_classes.tcc \ + /usr/include/c++/8/system_error \ + /usr/include/aarch64-linux-gnu/c++/8/bits/error_constants.h \ + /usr/include/c++/8/stdexcept /usr/include/c++/8/streambuf \ + /usr/include/c++/8/bits/streambuf.tcc \ + /usr/include/c++/8/bits/basic_ios.h \ + /usr/include/c++/8/bits/locale_facets.h /usr/include/c++/8/cwctype \ + /usr/include/wctype.h /usr/include/aarch64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/ctype_base.h \ + /usr/include/c++/8/bits/streambuf_iterator.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/ctype_inline.h \ + /usr/include/c++/8/bits/locale_facets.tcc \ + /usr/include/c++/8/bits/basic_ios.tcc /usr/include/c++/8/ostream \ + /usr/include/c++/8/bits/ostream.tcc /usr/include/c++/8/bits/istream.tcc \ + /usr/include/c++/8/bits/codecvt.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/basic_file.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++io.h \ + /usr/include/c++/8/bits/fstream.tcc /usr/include/c++/8/memory \ + /usr/include/c++/8/bits/stl_construct.h \ + /usr/include/c++/8/bits/stl_uninitialized.h \ + /usr/include/c++/8/bits/stl_tempbuf.h \ + /usr/include/c++/8/bits/stl_raw_storage_iter.h \ + /usr/include/c++/8/ext/concurrence.h \ + /usr/include/c++/8/bits/uses_allocator.h \ + /usr/include/c++/8/bits/unique_ptr.h /usr/include/c++/8/utility \ + /usr/include/c++/8/bits/stl_relops.h /usr/include/c++/8/tuple \ + /usr/include/c++/8/array /usr/include/c++/8/bits/invoke.h \ + /usr/include/c++/8/bits/shared_ptr.h \ + /usr/include/c++/8/bits/shared_ptr_base.h \ + /usr/include/c++/8/bits/allocated_ptr.h \ + /usr/include/c++/8/bits/refwrap.h \ + /usr/include/c++/8/ext/aligned_buffer.h \ + /usr/include/c++/8/bits/shared_ptr_atomic.h \ + /usr/include/c++/8/bits/atomic_base.h \ + /usr/include/c++/8/bits/atomic_lockfree_defines.h \ + /usr/include/c++/8/backward/auto_ptr.h \ + /usr/include/aarch64-linux-gnu/sys/stat.h \ + /usr/include/aarch64-linux-gnu/bits/stat.h \ + /usr/include/aarch64-linux-gnu/bits/statx.h /usr/include/fcntl.h \ + /usr/include/aarch64-linux-gnu/bits/fcntl.h \ + /usr/include/aarch64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/linux/falloc.h /usr/include/unistd.h \ + /usr/include/aarch64-linux-gnu/bits/posix_opt.h \ + /usr/include/aarch64-linux-gnu/bits/environments.h \ + /usr/include/aarch64-linux-gnu/bits/confname.h \ + /usr/include/aarch64-linux-gnu/bits/getopt_posix.h \ + /usr/include/aarch64-linux-gnu/bits/getopt_core.h diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/.Lcd.o.d b/device/gxx-linux/small_lcd/app_spi_lcd/.Lcd.o.d new file mode 100644 index 0000000..404f7b7 --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/.Lcd.o.d @@ -0,0 +1,172 @@ +Lcd.o: Lcd.cpp /usr/include/stdc-predef.h Lcd.h /usr/include/stdio.h \ + /usr/include/aarch64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/aarch64-linux-gnu/sys/cdefs.h \ + /usr/include/aarch64-linux-gnu/bits/wordsize.h \ + /usr/include/aarch64-linux-gnu/bits/long-double.h \ + /usr/include/aarch64-linux-gnu/gnu/stubs.h \ + /usr/include/aarch64-linux-gnu/gnu/stubs-lp64.h \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stddef.h \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stdarg.h \ + /usr/include/aarch64-linux-gnu/bits/types.h \ + /usr/include/aarch64-linux-gnu/bits/typesizes.h \ + /usr/include/aarch64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/aarch64-linux-gnu/bits/stdio_lim.h \ + /usr/include/aarch64-linux-gnu/bits/sys_errlist.h \ + /usr/include/c++/8/stdlib.h /usr/include/c++/8/cstdlib \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++config.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/os_defines.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/cpu_defines.h \ + /usr/include/stdlib.h /usr/include/aarch64-linux-gnu/bits/waitflags.h \ + /usr/include/aarch64-linux-gnu/bits/waitstatus.h \ + /usr/include/aarch64-linux-gnu/bits/floatn.h \ + /usr/include/aarch64-linux-gnu/bits/floatn-common.h \ + /usr/include/aarch64-linux-gnu/bits/types/locale_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/aarch64-linux-gnu/sys/types.h \ + /usr/include/aarch64-linux-gnu/bits/types/clock_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/time_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/timer_t.h \ + /usr/include/aarch64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/aarch64-linux-gnu/bits/endian.h \ + /usr/include/aarch64-linux-gnu/bits/byteswap.h \ + /usr/include/aarch64-linux-gnu/bits/uintn-identity.h \ + /usr/include/aarch64-linux-gnu/sys/select.h \ + /usr/include/aarch64-linux-gnu/bits/select.h \ + /usr/include/aarch64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/aarch64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/aarch64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/aarch64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/alloca.h /usr/include/aarch64-linux-gnu/bits/stdlib-float.h \ + /usr/include/c++/8/bits/std_abs.h /usr/include/c++/8/sstream \ + /usr/include/c++/8/istream /usr/include/c++/8/ios \ + /usr/include/c++/8/iosfwd /usr/include/c++/8/bits/stringfwd.h \ + /usr/include/c++/8/bits/memoryfwd.h /usr/include/c++/8/bits/postypes.h \ + /usr/include/c++/8/cwchar /usr/include/wchar.h \ + /usr/include/aarch64-linux-gnu/bits/wchar.h \ + /usr/include/aarch64-linux-gnu/bits/types/wint_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/c++/8/exception /usr/include/c++/8/bits/exception.h \ + /usr/include/c++/8/bits/exception_ptr.h \ + /usr/include/c++/8/bits/exception_defines.h \ + /usr/include/c++/8/bits/cxxabi_init_exception.h \ + /usr/include/c++/8/typeinfo /usr/include/c++/8/bits/hash_bytes.h \ + /usr/include/c++/8/new /usr/include/c++/8/bits/nested_exception.h \ + /usr/include/c++/8/bits/move.h /usr/include/c++/8/bits/concept_check.h \ + /usr/include/c++/8/type_traits /usr/include/c++/8/bits/char_traits.h \ + /usr/include/c++/8/bits/stl_algobase.h \ + /usr/include/c++/8/bits/functexcept.h \ + /usr/include/c++/8/bits/cpp_type_traits.h \ + /usr/include/c++/8/ext/type_traits.h \ + /usr/include/c++/8/ext/numeric_traits.h \ + /usr/include/c++/8/bits/stl_pair.h \ + /usr/include/c++/8/bits/stl_iterator_base_types.h \ + /usr/include/c++/8/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/8/debug/assertions.h \ + /usr/include/c++/8/bits/stl_iterator.h \ + /usr/include/c++/8/bits/ptr_traits.h /usr/include/c++/8/debug/debug.h \ + /usr/include/c++/8/bits/predefined_ops.h /usr/include/c++/8/cstdint \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stdint.h /usr/include/stdint.h \ + /usr/include/aarch64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/c++/8/bits/localefwd.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++locale.h \ + /usr/include/c++/8/clocale /usr/include/locale.h \ + /usr/include/aarch64-linux-gnu/bits/locale.h /usr/include/c++/8/cctype \ + /usr/include/ctype.h /usr/include/c++/8/bits/ios_base.h \ + /usr/include/c++/8/ext/atomicity.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/gthr.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/aarch64-linux-gnu/bits/sched.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/aarch64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/aarch64-linux-gnu/bits/time.h \ + /usr/include/aarch64-linux-gnu/bits/timex.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/aarch64-linux-gnu/bits/setjmp.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/atomic_word.h \ + /usr/include/c++/8/bits/locale_classes.h /usr/include/c++/8/string \ + /usr/include/c++/8/bits/allocator.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++allocator.h \ + /usr/include/c++/8/ext/new_allocator.h \ + /usr/include/c++/8/bits/ostream_insert.h \ + /usr/include/c++/8/bits/cxxabi_forced.h \ + /usr/include/c++/8/bits/stl_function.h \ + /usr/include/c++/8/backward/binders.h \ + /usr/include/c++/8/bits/range_access.h \ + /usr/include/c++/8/initializer_list \ + /usr/include/c++/8/bits/basic_string.h \ + /usr/include/c++/8/ext/alloc_traits.h \ + /usr/include/c++/8/bits/alloc_traits.h \ + /usr/include/c++/8/ext/string_conversions.h /usr/include/c++/8/cstdio \ + /usr/include/c++/8/cerrno /usr/include/errno.h \ + /usr/include/aarch64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/aarch64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/aarch64-linux-gnu/bits/types/error_t.h \ + /usr/include/c++/8/bits/functional_hash.h \ + /usr/include/c++/8/bits/basic_string.tcc \ + /usr/include/c++/8/bits/locale_classes.tcc \ + /usr/include/c++/8/system_error \ + /usr/include/aarch64-linux-gnu/c++/8/bits/error_constants.h \ + /usr/include/c++/8/stdexcept /usr/include/c++/8/streambuf \ + /usr/include/c++/8/bits/streambuf.tcc \ + /usr/include/c++/8/bits/basic_ios.h \ + /usr/include/c++/8/bits/locale_facets.h /usr/include/c++/8/cwctype \ + /usr/include/wctype.h /usr/include/aarch64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/ctype_base.h \ + /usr/include/c++/8/bits/streambuf_iterator.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/ctype_inline.h \ + /usr/include/c++/8/bits/locale_facets.tcc \ + /usr/include/c++/8/bits/basic_ios.tcc /usr/include/c++/8/ostream \ + /usr/include/c++/8/bits/ostream.tcc /usr/include/c++/8/bits/istream.tcc \ + /usr/include/c++/8/bits/sstream.tcc /usr/include/unistd.h \ + /usr/include/aarch64-linux-gnu/bits/posix_opt.h \ + /usr/include/aarch64-linux-gnu/bits/environments.h \ + /usr/include/aarch64-linux-gnu/bits/confname.h \ + /usr/include/aarch64-linux-gnu/bits/getopt_posix.h \ + /usr/include/aarch64-linux-gnu/bits/getopt_core.h DevUtil.h \ + /usr/include/c++/8/fstream /usr/include/c++/8/bits/codecvt.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/basic_file.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++io.h \ + /usr/include/c++/8/bits/fstream.tcc /usr/include/c++/8/memory \ + /usr/include/c++/8/bits/stl_construct.h \ + /usr/include/c++/8/bits/stl_uninitialized.h \ + /usr/include/c++/8/bits/stl_tempbuf.h \ + /usr/include/c++/8/bits/stl_raw_storage_iter.h \ + /usr/include/c++/8/ext/concurrence.h \ + /usr/include/c++/8/bits/uses_allocator.h \ + /usr/include/c++/8/bits/unique_ptr.h /usr/include/c++/8/utility \ + /usr/include/c++/8/bits/stl_relops.h /usr/include/c++/8/tuple \ + /usr/include/c++/8/array /usr/include/c++/8/bits/invoke.h \ + /usr/include/c++/8/bits/shared_ptr.h \ + /usr/include/c++/8/bits/shared_ptr_base.h \ + /usr/include/c++/8/bits/allocated_ptr.h \ + /usr/include/c++/8/bits/refwrap.h \ + /usr/include/c++/8/ext/aligned_buffer.h \ + /usr/include/c++/8/bits/shared_ptr_atomic.h \ + /usr/include/c++/8/bits/atomic_base.h \ + /usr/include/c++/8/bits/atomic_lockfree_defines.h \ + /usr/include/c++/8/backward/auto_ptr.h filetools.h \ + /usr/include/c++/8/vector /usr/include/c++/8/bits/stl_vector.h \ + /usr/include/c++/8/bits/stl_bvector.h /usr/include/c++/8/bits/vector.tcc \ + /usr/include/c++/8/chrono /usr/include/c++/8/ratio \ + /usr/include/c++/8/limits /usr/include/c++/8/ctime \ + /usr/include/c++/8/bits/parse_numbers.h Gpio.h \ + /usr/include/aarch64-linux-gnu/sys/stat.h \ + /usr/include/aarch64-linux-gnu/bits/stat.h \ + /usr/include/aarch64-linux-gnu/bits/statx.h /usr/include/fcntl.h \ + /usr/include/aarch64-linux-gnu/bits/fcntl.h \ + /usr/include/aarch64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/linux/falloc.h diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/.main.o.d b/device/gxx-linux/small_lcd/app_spi_lcd/.main.o.d new file mode 100644 index 0000000..3a116f4 --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/.main.o.d @@ -0,0 +1,172 @@ +main.o: main.cpp /usr/include/stdc-predef.h /usr/include/stdio.h \ + /usr/include/aarch64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/aarch64-linux-gnu/sys/cdefs.h \ + /usr/include/aarch64-linux-gnu/bits/wordsize.h \ + /usr/include/aarch64-linux-gnu/bits/long-double.h \ + /usr/include/aarch64-linux-gnu/gnu/stubs.h \ + /usr/include/aarch64-linux-gnu/gnu/stubs-lp64.h \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stddef.h \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stdarg.h \ + /usr/include/aarch64-linux-gnu/bits/types.h \ + /usr/include/aarch64-linux-gnu/bits/typesizes.h \ + /usr/include/aarch64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/aarch64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/aarch64-linux-gnu/bits/stdio_lim.h \ + /usr/include/aarch64-linux-gnu/bits/sys_errlist.h \ + /usr/include/c++/8/stdlib.h /usr/include/c++/8/cstdlib \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++config.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/os_defines.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/cpu_defines.h \ + /usr/include/stdlib.h /usr/include/aarch64-linux-gnu/bits/waitflags.h \ + /usr/include/aarch64-linux-gnu/bits/waitstatus.h \ + /usr/include/aarch64-linux-gnu/bits/floatn.h \ + /usr/include/aarch64-linux-gnu/bits/floatn-common.h \ + /usr/include/aarch64-linux-gnu/bits/types/locale_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/aarch64-linux-gnu/sys/types.h \ + /usr/include/aarch64-linux-gnu/bits/types/clock_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/time_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/timer_t.h \ + /usr/include/aarch64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/aarch64-linux-gnu/bits/endian.h \ + /usr/include/aarch64-linux-gnu/bits/byteswap.h \ + /usr/include/aarch64-linux-gnu/bits/uintn-identity.h \ + /usr/include/aarch64-linux-gnu/sys/select.h \ + /usr/include/aarch64-linux-gnu/bits/select.h \ + /usr/include/aarch64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/aarch64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/aarch64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/aarch64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/alloca.h /usr/include/aarch64-linux-gnu/bits/stdlib-float.h \ + /usr/include/c++/8/bits/std_abs.h /usr/include/c++/8/sstream \ + /usr/include/c++/8/istream /usr/include/c++/8/ios \ + /usr/include/c++/8/iosfwd /usr/include/c++/8/bits/stringfwd.h \ + /usr/include/c++/8/bits/memoryfwd.h /usr/include/c++/8/bits/postypes.h \ + /usr/include/c++/8/cwchar /usr/include/wchar.h \ + /usr/include/aarch64-linux-gnu/bits/wchar.h \ + /usr/include/aarch64-linux-gnu/bits/types/wint_t.h \ + /usr/include/aarch64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/c++/8/exception /usr/include/c++/8/bits/exception.h \ + /usr/include/c++/8/bits/exception_ptr.h \ + /usr/include/c++/8/bits/exception_defines.h \ + /usr/include/c++/8/bits/cxxabi_init_exception.h \ + /usr/include/c++/8/typeinfo /usr/include/c++/8/bits/hash_bytes.h \ + /usr/include/c++/8/new /usr/include/c++/8/bits/nested_exception.h \ + /usr/include/c++/8/bits/move.h /usr/include/c++/8/bits/concept_check.h \ + /usr/include/c++/8/type_traits /usr/include/c++/8/bits/char_traits.h \ + /usr/include/c++/8/bits/stl_algobase.h \ + /usr/include/c++/8/bits/functexcept.h \ + /usr/include/c++/8/bits/cpp_type_traits.h \ + /usr/include/c++/8/ext/type_traits.h \ + /usr/include/c++/8/ext/numeric_traits.h \ + /usr/include/c++/8/bits/stl_pair.h \ + /usr/include/c++/8/bits/stl_iterator_base_types.h \ + /usr/include/c++/8/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/8/debug/assertions.h \ + /usr/include/c++/8/bits/stl_iterator.h \ + /usr/include/c++/8/bits/ptr_traits.h /usr/include/c++/8/debug/debug.h \ + /usr/include/c++/8/bits/predefined_ops.h /usr/include/c++/8/cstdint \ + /usr/lib/gcc/aarch64-linux-gnu/8/include/stdint.h /usr/include/stdint.h \ + /usr/include/aarch64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/c++/8/bits/localefwd.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++locale.h \ + /usr/include/c++/8/clocale /usr/include/locale.h \ + /usr/include/aarch64-linux-gnu/bits/locale.h /usr/include/c++/8/cctype \ + /usr/include/ctype.h /usr/include/c++/8/bits/ios_base.h \ + /usr/include/c++/8/ext/atomicity.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/gthr.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/aarch64-linux-gnu/bits/sched.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/aarch64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/aarch64-linux-gnu/bits/time.h \ + /usr/include/aarch64-linux-gnu/bits/timex.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/aarch64-linux-gnu/bits/setjmp.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/atomic_word.h \ + /usr/include/c++/8/bits/locale_classes.h /usr/include/c++/8/string \ + /usr/include/c++/8/bits/allocator.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++allocator.h \ + /usr/include/c++/8/ext/new_allocator.h \ + /usr/include/c++/8/bits/ostream_insert.h \ + /usr/include/c++/8/bits/cxxabi_forced.h \ + /usr/include/c++/8/bits/stl_function.h \ + /usr/include/c++/8/backward/binders.h \ + /usr/include/c++/8/bits/range_access.h \ + /usr/include/c++/8/initializer_list \ + /usr/include/c++/8/bits/basic_string.h \ + /usr/include/c++/8/ext/alloc_traits.h \ + /usr/include/c++/8/bits/alloc_traits.h \ + /usr/include/c++/8/ext/string_conversions.h /usr/include/c++/8/cstdio \ + /usr/include/c++/8/cerrno /usr/include/errno.h \ + /usr/include/aarch64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/aarch64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/aarch64-linux-gnu/bits/types/error_t.h \ + /usr/include/c++/8/bits/functional_hash.h \ + /usr/include/c++/8/bits/basic_string.tcc \ + /usr/include/c++/8/bits/locale_classes.tcc \ + /usr/include/c++/8/system_error \ + /usr/include/aarch64-linux-gnu/c++/8/bits/error_constants.h \ + /usr/include/c++/8/stdexcept /usr/include/c++/8/streambuf \ + /usr/include/c++/8/bits/streambuf.tcc \ + /usr/include/c++/8/bits/basic_ios.h \ + /usr/include/c++/8/bits/locale_facets.h /usr/include/c++/8/cwctype \ + /usr/include/wctype.h /usr/include/aarch64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/ctype_base.h \ + /usr/include/c++/8/bits/streambuf_iterator.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/ctype_inline.h \ + /usr/include/c++/8/bits/locale_facets.tcc \ + /usr/include/c++/8/bits/basic_ios.tcc /usr/include/c++/8/ostream \ + /usr/include/c++/8/bits/ostream.tcc /usr/include/c++/8/bits/istream.tcc \ + /usr/include/c++/8/bits/sstream.tcc /usr/include/unistd.h \ + /usr/include/aarch64-linux-gnu/bits/posix_opt.h \ + /usr/include/aarch64-linux-gnu/bits/environments.h \ + /usr/include/aarch64-linux-gnu/bits/confname.h \ + /usr/include/aarch64-linux-gnu/bits/getopt_posix.h \ + /usr/include/aarch64-linux-gnu/bits/getopt_core.h DevUtil.h \ + /usr/include/c++/8/fstream /usr/include/c++/8/bits/codecvt.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/basic_file.h \ + /usr/include/aarch64-linux-gnu/c++/8/bits/c++io.h \ + /usr/include/c++/8/bits/fstream.tcc /usr/include/c++/8/memory \ + /usr/include/c++/8/bits/stl_construct.h \ + /usr/include/c++/8/bits/stl_uninitialized.h \ + /usr/include/c++/8/bits/stl_tempbuf.h \ + /usr/include/c++/8/bits/stl_raw_storage_iter.h \ + /usr/include/c++/8/ext/concurrence.h \ + /usr/include/c++/8/bits/uses_allocator.h \ + /usr/include/c++/8/bits/unique_ptr.h /usr/include/c++/8/utility \ + /usr/include/c++/8/bits/stl_relops.h /usr/include/c++/8/tuple \ + /usr/include/c++/8/array /usr/include/c++/8/bits/invoke.h \ + /usr/include/c++/8/bits/shared_ptr.h \ + /usr/include/c++/8/bits/shared_ptr_base.h \ + /usr/include/c++/8/bits/allocated_ptr.h \ + /usr/include/c++/8/bits/refwrap.h \ + /usr/include/c++/8/ext/aligned_buffer.h \ + /usr/include/c++/8/bits/shared_ptr_atomic.h \ + /usr/include/c++/8/bits/atomic_base.h \ + /usr/include/c++/8/bits/atomic_lockfree_defines.h \ + /usr/include/c++/8/backward/auto_ptr.h filetools.h \ + /usr/include/c++/8/vector /usr/include/c++/8/bits/stl_vector.h \ + /usr/include/c++/8/bits/stl_bvector.h /usr/include/c++/8/bits/vector.tcc \ + /usr/include/c++/8/chrono /usr/include/c++/8/ratio \ + /usr/include/c++/8/limits /usr/include/c++/8/ctime \ + /usr/include/c++/8/bits/parse_numbers.h Gpio.h Lcd.h \ + /usr/include/aarch64-linux-gnu/sys/stat.h \ + /usr/include/aarch64-linux-gnu/bits/stat.h \ + /usr/include/aarch64-linux-gnu/bits/statx.h /usr/include/fcntl.h \ + /usr/include/aarch64-linux-gnu/bits/fcntl.h \ + /usr/include/aarch64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/aarch64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/linux/falloc.h diff --git a/device/gxx-linux/motor_run/DevUtil.cpp b/device/gxx-linux/small_lcd/app_spi_lcd/DevUtil.cpp similarity index 79% rename from device/gxx-linux/motor_run/DevUtil.cpp rename to device/gxx-linux/small_lcd/app_spi_lcd/DevUtil.cpp index 310aca3..6b2ab23 100644 --- a/device/gxx-linux/motor_run/DevUtil.cpp +++ b/device/gxx-linux/small_lcd/app_spi_lcd/DevUtil.cpp @@ -1,8 +1,12 @@ #include "DevUtil.h" #include -#define IOEXPORTPATH "/sys/class/gpio/export" -#define PWMEXPORTPATH "/sys/class/pwm/pwmchip%d/export" +#include +#include +#include +#include +#include + int read_dev_i(std::string path) { int val = -1; std::ifstream ifin(path.c_str()); @@ -26,5 +30,5 @@ DeviceExport::DeviceExport() 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/small_lcd/app_spi_lcd/DevUtil.h b/device/gxx-linux/small_lcd/app_spi_lcd/DevUtil.h new file mode 100644 index 0000000..7c250de --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/DevUtil.h @@ -0,0 +1,99 @@ +#pragma once +#include +#include +#include + +#define IOEXPORTPATH "/sys/class/gpio/export" +#define PWMEXPORTPATH "/sys/class/pwm/pwmchip%d/export" + +template +std::string string_format(const std::string& format, Args ... args) { + size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; + std::unique_ptr buf(new char[size]); + snprintf(buf.get(), size, format.c_str(), args ...); + return std::string(buf.get(), buf.get() + size - 1); +} + +template +void write_dev(std::string path, T value) { + std::ofstream ofout(path); + ofout << value; +} + +extern int read_dev_i(std::string path); + +extern std::string read_dev_s(std::string path); + +enum PORTS +{ + Start = 171, + Stop = 49, + Power = 5, + Fpga_Load = 8, + +#ifndef G300 + Power_12v_Off = 12, +#endif + + MotorPower = 48, + CuoZhiMotor_Reset = 56, + CuoZhiMotor_Sleep = 57, + CuoZhiMotor_Enable = 58, + + CuoZhiMotor_Direction = 62, + CuoZhiMotor_Decay = 63, + CuoZhiMotor_Home = 184, + CuoZhiMotor_Fault = 185, + + CuoZhiMotor_Mode0 = 59, + CuoZhiMotor_Mode1 = 60, + CuoZhiMotor_Mode2 = 61, + Cover = 189,// 'GPIO6A5' opened:0 ; closed:1 + + Paper = 225,// 'GPIO7B1' has paper:0 ; no paper:1 + Scan = 226,// 'GPIO7B2' no paper:0 ; has paper:1 + Scan1 = 102, + Double_Paper = 219,// 'GPIO7A3' not doubled:0 ; doubled:1 + Double_Enable = 250,// 'GPIO8A2' off: 0 ; on: 1 + + ZouZhiMotor_Reset = 64, + ZouZhiMotor_Sleep = 65, + ZouZhiMotor_Enable = 66, + ZouZhiMotor_Direction = 70, + + ZouZhiMotor_Decay = 71, + ZouZhiMotor_Home = 187, + ZouZhiMotor_Fault = 188, + ZouZhiMotor_Mode0 = 67, + + ZouZhiMotor_Mode1 = 68, + ZouZhiMotor_Mode2 = 69, + CIS_3v3_Off = 96, + CIS_5v_En = 98, + + Fpga_InitDone = 99, + Image_In_Transfer = 101, + Fpga_Reset = 232 +}; + +class DeviceExport { +public: + DeviceExport(); +private: +#ifndef G300 + const int ports[37] = { Start , Stop, Power, Fpga_Load, Power_12v_Off, MotorPower, CuoZhiMotor_Reset, CuoZhiMotor_Sleep, CuoZhiMotor_Enable, + CuoZhiMotor_Direction, CuoZhiMotor_Decay, CuoZhiMotor_Home, CuoZhiMotor_Fault , CuoZhiMotor_Mode0 , + CuoZhiMotor_Mode1, CuoZhiMotor_Mode2, Cover, Paper, Scan, Scan1,Double_Paper, Double_Enable, + ZouZhiMotor_Reset, ZouZhiMotor_Sleep, ZouZhiMotor_Enable, ZouZhiMotor_Direction, ZouZhiMotor_Decay, + ZouZhiMotor_Home, ZouZhiMotor_Fault, ZouZhiMotor_Mode0, ZouZhiMotor_Mode1, ZouZhiMotor_Mode2, + CIS_3v3_Off, CIS_5v_En, Fpga_InitDone, Image_In_Transfer, Fpga_Reset }; +#else + const int ports[36] = { Start , Stop, Power, Fpga_Load, MotorPower, CuoZhiMotor_Reset, CuoZhiMotor_Sleep, CuoZhiMotor_Enable, + CuoZhiMotor_Direction, CuoZhiMotor_Decay, CuoZhiMotor_Home, CuoZhiMotor_Fault , CuoZhiMotor_Mode0 , + CuoZhiMotor_Mode1, CuoZhiMotor_Mode2, Cover, Paper, Scan, Scan1, Double_Paper, Double_Enable, + ZouZhiMotor_Reset, ZouZhiMotor_Sleep, ZouZhiMotor_Enable, ZouZhiMotor_Direction, ZouZhiMotor_Decay, + ZouZhiMotor_Home, ZouZhiMotor_Fault, ZouZhiMotor_Mode0, ZouZhiMotor_Mode1, ZouZhiMotor_Mode2, + CIS_3v3_Off, CIS_5v_En, Fpga_InitDone, Image_In_Transfer, Fpga_Reset }; +#endif + const int pwms[2] = { 0, 1 }; +}; \ No newline at end of file diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/DevUtil.o b/device/gxx-linux/small_lcd/app_spi_lcd/DevUtil.o new file mode 100644 index 0000000..578ec76 Binary files /dev/null and b/device/gxx-linux/small_lcd/app_spi_lcd/DevUtil.o differ diff --git a/device/gxx-linux/motor_run/Gpio.cpp b/device/gxx-linux/small_lcd/app_spi_lcd/Gpio.cpp similarity index 68% rename from device/gxx-linux/motor_run/Gpio.cpp rename to device/gxx-linux/small_lcd/app_spi_lcd/Gpio.cpp index 8fa9e8d..0e9d593 100644 --- a/device/gxx-linux/motor_run/Gpio.cpp +++ b/device/gxx-linux/small_lcd/app_spi_lcd/Gpio.cpp @@ -1,6 +1,13 @@ -#include +// +// Created by yingluo907 on 2019/4/11. +// #include "Gpio.h" #include "DevUtil.h" +#include +#include +#include +#include +#include #define IOPATH "%s/gpio%d/%s" @@ -19,12 +26,9 @@ Gpio::Gpio(int port) 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; + sprintf (fname, "/sys/class/gpio/gpio%d/value", port); + gpio_fd = open (fname, O_RDWR); + printf("Gpio::gpio%d.fd = %d.\n",port,gpio_fd); } int Gpio::getPort() @@ -34,7 +38,13 @@ int Gpio::getPort() void Gpio::setValue(GpioLevel level) { - write_dev(path_value, level); + //write_dev(path_value, level); + if(port == 153 || port == 150) + printf("\n Gpio %d setvalue %d ",port,level==Low?0:1); + if (level == Low) + write (gpio_fd, "0\n", 2); + else + write (gpio_fd, "1\n", 2); } Gpio::GpioLevel Gpio::getValue() { @@ -48,6 +58,8 @@ std::string Gpio::getDirection() void Gpio::setDirection(std::string direction) { + if(port == 153 || port == 150) + printf("\n Gpio %d setDirection %s ",port,direction.c_str()); write_dev(path_direction, direction); } @@ -71,9 +83,8 @@ std::string Gpio::getEdge() return read_dev_s(path_edge); } -GpioOut::GpioOut(int port) : Gpio(port) +GpioOut::GpioOut(int port) : + Gpio(port) { setDirection(out); } - - diff --git a/device/gxx-linux/motor_run/Gpio.h b/device/gxx-linux/small_lcd/app_spi_lcd/Gpio.h similarity index 84% rename from device/gxx-linux/motor_run/Gpio.h rename to device/gxx-linux/small_lcd/app_spi_lcd/Gpio.h index ba785c5..a1c820c 100644 --- a/device/gxx-linux/motor_run/Gpio.h +++ b/device/gxx-linux/small_lcd/app_spi_lcd/Gpio.h @@ -1,4 +1,9 @@ -#pragma once +// +// Created by yingluo907 on 2019/4/11. +// + +#ifndef HGSCANSERVICE_GPIO_H +#define HGSCANSERVICE_GPIO_H #include class Gpio { @@ -7,18 +12,17 @@ public: 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(); @@ -40,8 +44,8 @@ private: std::string path_edge = "edge"; std::string path_direction = "direction"; std::string path_active_low = "active_low"; - - + int gpio_fd; + char fname[128]; }; class GpioOut : public Gpio @@ -51,3 +55,4 @@ public: }; +#endif //HGSCANSERVICE_GPIO_H diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/Gpio.o b/device/gxx-linux/small_lcd/app_spi_lcd/Gpio.o new file mode 100644 index 0000000..9a4bef1 Binary files /dev/null and b/device/gxx-linux/small_lcd/app_spi_lcd/Gpio.o differ diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/Lcd.cpp b/device/gxx-linux/small_lcd/app_spi_lcd/Lcd.cpp new file mode 100644 index 0000000..ba8c3b3 --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/Lcd.cpp @@ -0,0 +1,428 @@ +#include "Lcd.h" + +//下载中 +unsigned char Downloading[]={ +0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00,0x00, +0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, +0x08,0x08,0x88,0xC8,0x38,0x0C,0x0B,0x08,0x08,0xE8,0x08,0x08,0x08,0x08,0x08,0x00, +0x02,0x01,0x00,0xFF,0x40,0x41,0x41,0x41,0x41,0x7F,0x41,0x41,0x41,0x41,0x40,0x00, +0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x42,0x82,0x02,0x02,0x02,0x02,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,0x06,0x00,0x00,0x00, +0x90,0x94,0x94,0xF4,0x9F,0x94,0x94,0x94,0x10,0x10,0xFF,0x10,0x12,0xD4,0x10,0x00, +0x20,0x26,0x25,0x24,0xFE,0x14,0x14,0x14,0x80,0x40,0x27,0x18,0x26,0x41,0xF0,0x00, +0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00, +0x00,0x00,0x0F,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x0F,0x00,0x00,0x00, +}; +//下载成功 +unsigned char downloadSuccess[] +{ +0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x42,0x82,0x02,0x02,0x02,0x02,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,0x06,0x00,0x00,0x00, +0x90,0x94,0x94,0xF4,0x9F,0x94,0x94,0x94,0x10,0x10,0xFF,0x10,0x12,0xD4,0x10,0x00, +0x20,0x26,0x25,0x24,0xFE,0x14,0x14,0x14,0x80,0x40,0x27,0x18,0x26,0x41,0xF0,0x00, +0x10,0x0C,0x04,0x24,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x24,0x04,0x14,0x0C,0x00, +0x00,0x81,0x81,0x41,0x31,0x0F,0x01,0x01,0x01,0x7F,0x81,0x81,0x81,0xF1,0x00,0x00, +0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x08,0x08,0xFF,0x08,0x09,0x0A,0xC8,0x08,0x00, +0x80,0x60,0x1F,0x00,0x10,0x20,0x1F,0x80,0x40,0x21,0x16,0x18,0x26,0x41,0xF8,0x00, +0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +//下载失败 +unsigned char downloadFailure[] +{ +0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x42,0x82,0x02,0x02,0x02,0x02,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,0x06,0x00,0x00,0x00, +0x90,0x94,0x94,0xF4,0x9F,0x94,0x94,0x94,0x10,0x10,0xFF,0x10,0x12,0xD4,0x10,0x00, +0x20,0x26,0x25,0x24,0xFE,0x14,0x14,0x14,0x80,0x40,0x27,0x18,0x26,0x41,0xF0,0x00, +0x00,0x40,0x30,0x1E,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, +0x81,0x81,0x41,0x21,0x11,0x0D,0x03,0x01,0x03,0x0D,0x11,0x21,0x41,0x81,0x81,0x00, +0x00,0xFE,0x02,0xFA,0x02,0xFE,0x40,0x20,0xD8,0x17,0x10,0x10,0xF0,0x10,0x10,0x00, +0x80,0x47,0x30,0x0F,0x10,0x67,0x80,0x40,0x21,0x16,0x08,0x16,0x21,0x40,0x80,0x00, +0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +unsigned char ChooseAgain[]{ +0x40,0x42,0xCC,0x00,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00, +0x00,0x00,0x7F,0x20,0x10,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00, +0x40,0x40,0x42,0xCC,0x00,0x50,0x4E,0xC8,0x48,0x7F,0xC8,0x48,0x48,0x40,0x00,0x00, +0x00,0x40,0x20,0x1F,0x20,0x50,0x4C,0x43,0x40,0x40,0x4F,0x50,0x50,0x5C,0x40,0x00, +0x10,0x10,0xFF,0x10,0x00,0x82,0x86,0x4A,0x52,0xA2,0x52,0x4A,0x86,0x80,0x80,0x00, +0x42,0x82,0x7F,0x01,0x00,0x10,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x10,0x00,0x00, +0x10,0x10,0x10,0xFF,0x90,0x20,0x98,0x88,0x88,0xE9,0x8E,0x88,0x88,0xA8,0x98,0x00, +0x02,0x42,0x81,0x7F,0x00,0x00,0x80,0x84,0x4B,0x28,0x10,0x28,0x47,0x80,0x00,0x00, +0x40,0x30,0xEF,0x24,0x24,0x80,0xE4,0x9C,0x10,0x54,0x54,0xFF,0x54,0x7C,0x10,0x00, +0x01,0x01,0x7F,0x21,0x51,0x26,0x18,0x27,0x44,0x45,0x45,0x5F,0x45,0x45,0x44,0x00, +}; + + +Lcd::Lcd():spi_sck(51),spi_sda(72),spi_cs(154),spi_reset(150),spi_rs(156),COM_BOOT0(153) + +{ + printf("Lcd()\n"); + write_dev(IOEXPORTPATH, 51); + write_dev(IOEXPORTPATH, 72); + write_dev(IOEXPORTPATH, 154); + write_dev(IOEXPORTPATH, 150); + write_dev(IOEXPORTPATH, 156); + write_dev(IOEXPORTPATH, 153); + COM_BOOT0.setDirection(Gpio::out); + spi_sck.setDirection(Gpio::out); + spi_sda.setDirection(Gpio::out); + spi_cs.setDirection(Gpio::out); + spi_reset.setDirection(Gpio::out); + spi_rs.setDirection(Gpio::out); + + + COM_BOOT0.setValue(Gpio::Low); + spi_sck.setValue(Gpio::High); + spi_sda.setValue(Gpio::High); + spi_cs.setValue(Gpio::High); + spi_reset.setValue(Gpio::High); + spi_rs.setValue(Gpio::High); +} + +/*延时*/ +void delay(int i) +{ + int j,k; + for(j=0;j>4)&0x0f)+0x10); //设置列地址的高4位 + Lcd_Transfer_Command(column&0x0f); //设置列地址的低4位 +} + +/*全屏清屏*/ +/*void Lcd::Lcd_Clear_screen() +{ + //COM_BOOT0.setValue(Gpio::Low); + unsigned char i,j; + spi_cs.setValue(Gpio::Low); + for(i=0;i<9;i++) + { + Lcd_Address(1+i,1); + for(j=0;j<132;j++) + { + Lcd_Transfer_data(0x00); + } + } + spi_cs.setValue(Gpio::High); +}*/ +void Lcd::Lcd_Clear_screen() +{ + unsigned char i,j; + //spi_cs.setValue(Gpio::Low); + for(i=0; i<4; i++) + { + Lcd_Transfer_Command(0xb0+i); + Lcd_Transfer_Command(0x10); + Lcd_Transfer_Command(0x00); + for(j = 0;j<132;j++) + { + Lcd_Transfer_data(0x00); + } + + } +} + + +//===显示测试画面:例如全显示,隔行显示,隔列显示,雪花显示===== +void Lcd::Lcd_Test_Display(unsigned char data1, unsigned char data2) +{ + int i,j; + for(j=0;j<8;j++) + { + spi_cs.setValue(Gpio::Low); + Lcd_Address(j+1,1); + for(i=0;i<128;i++) + { + Lcd_Transfer_data(data1); + Lcd_Transfer_data(data2); + } + } +} + +/*显示128x64点阵图像*/ +void Lcd::Lcd_Display_Graphic_128x64(unsigned char page, unsigned char column, unsigned char *dp) +{ + int i,j; + for(j=0;j<8;j++) + { + spi_cs.setValue(Gpio::Low); + Lcd_Address(page+j,column); + for(i=0;i<128;i++) + { + Lcd_Transfer_data(*dp); + dp++; + } + } +} + +/*显示32x32点阵图像、汉字、生僻字或32x32点阵的其他图标*/ +void Lcd::Lcd_Display_graphic_32x32(unsigned char page, unsigned char column, unsigned char *dp) +{ + unsigned char i,j; + spi_cs.setValue(Gpio::Low); + for(j=0;j<4;j++) + { + Lcd_Address(page+j,column); + for (i=0;i<31;i++) + { + Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + dp++; + } + } +} + + +/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/ +void Lcd::Lcd_Display_Graphic_16x16_2(unsigned char reverse,unsigned char page,unsigned char column,unsigned char *dp) +{ + unsigned char i,j; + + spi_cs.setValue(Gpio::Low); + for(j=0;j<2;j++) + { + Lcd_Address(page+j,column); + for (i=0;i<16;i++) + { + if(reverse==1) + Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + else + Lcd_Transfer_data(~*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + dp++; + } + } + spi_cs.setValue(Gpio::High); +} + +/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/ +void Lcd::Lcd_Display_Graphic_16x16(unsigned char page, unsigned char column, unsigned char *dp, unsigned int wordcount) +{ + unsigned char i,j,k; + spi_cs.setValue(Gpio::Low); + for (k = 0; k < wordcount; k++) + { + for(j=0;j<2;j++) + { + Lcd_Address(page+j,column+16 * k); + for (i=0;i<16;i++) + { + Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + dp++; + } + } + } + spi_cs.setValue(Gpio::High); + +} + +/*显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标*/ +void Lcd::Lcd_Display_Graphic_8x16(unsigned char page, unsigned char column,unsigned char *dp) +{ + unsigned char i,j; + spi_cs.setValue(Gpio::Low); + for(j=0;j<2;j++) + { + Lcd_Address(page+j,column); + for (i=0;i<8;i++) + { + Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/ + dp++; + } + } + spi_cs.setValue(Gpio::High); +} + +/*void Lcd::Lcd_Display_String_8x16(unsigned int page, unsigned int column, const char *text) +{ + unsigned int i=0,j,k,n; + //COM_BOOT0.setValue(Gpio::Low); + spi_cs.setValue(Gpio::Low); + while(text[i]>0x00) + { + if((text[i]>=0x20)&&(text[i]<=0x7e)) + { + j=text[i]-0x20; + for(n=0;n<2;n++) + { + Lcd_Address(page+n,column); + for(k=0;k<8;k++) + { + Lcd_Transfer_data(ascii_table_8x16[j][k+8*n]);//显示5x7的ASCII字到LCD上,y为页地址,x为列地址,最后为数据 + } + } + i++; + column+=8; + + } + else + i++; + } +} +*/ +/*void Lcd::Lcd_Display_String_5x8(unsigned int page, unsigned int column, const char *text) +{ + unsigned int i=0,j,k; + spi_cs.setValue(Gpio::Low); + while(text[i]>0x00) + { + if((text[i]>=0x20)&&(text[i]<0x7e)) + { + j=text[i]-0x20; + Lcd_Address(page,column); + for(k=0;k<5;k++) + { + Lcd_Transfer_data(ascii_table_5x8[j][k]);//显示5x7的ASCII字到LCD上,y为页地址,x为列地址,最后为数据 + } + i++; + column+=6; + } + else + i++; + } +} +*/ +void Lcd::display_Selective(int selective) +{ + COM_BOOT0.setValue(Gpio::Low); + switch(selective) + { + case 1: + Lcd_Display_Graphic_16x16(1, 1, Downloading, 5); + Lcd_Display_Graphic_16x16(3, 1, Downloading, 5); + break; + case 2: + Lcd_Display_Graphic_16x16(1, 1, downloadSuccess, 5); + Lcd_Display_Graphic_16x16(3, 1, downloadSuccess, 5); + break; + case 3: + Lcd_Display_Graphic_16x16(1, 1, downloadFailure, 5); + Lcd_Display_Graphic_16x16(3, 1, downloadFailure, 5); + break; + case 4: + Lcd_Display_Graphic_16x16(1, 1, ChooseAgain, 5); + Lcd_Display_Graphic_16x16(3, 1, ChooseAgain, 5); + break; + default: + printf("selective display is erro!\n"); + break; + } +} diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/Lcd.h b/device/gxx-linux/small_lcd/app_spi_lcd/Lcd.h new file mode 100644 index 0000000..2013960 --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/Lcd.h @@ -0,0 +1,73 @@ +#ifndef HGSCANSERVICE_LCD_H +#define HGSCANSERVICE_LCD_H + +#include +#include +#include +#include +#include +#include "DevUtil.h" +#include "filetools.h" +#include "Gpio.h" +#include +#include +#include + + +class Lcd +{ +private: + Gpio spi_sck; + Gpio spi_sda; + Gpio spi_cs; + Gpio spi_reset; + Gpio spi_rs; + Gpio COM_BOOT0; + +public: + Lcd(); + /*=======写指令========*/ + void Lcd_Transfer_Command(int data1); + + /*--------写数据------------*/ + void Lcd_Transfer_data(int data1); + + /*大LCD模块初始化*/ + void Small_Lcd_Initial_Lcd(); + + void Big_Lcd_Initial_Lcd(); + + void Lcd_Address(unsigned char page, unsigned char column); + + /*全屏清屏*/ + void Lcd_Clear_screen(); + + //===显示测试画面:例如全显示,隔行显示,隔列显示,雪花显示===== + void Lcd_Test_Display(unsigned char data1, unsigned char data2); + + /*显示128x64点阵图像*/ + void Lcd_Display_Graphic_128x64(unsigned char page, unsigned char column, unsigned char *dp); + + /*显示32x32点阵图像、汉字、生僻字或32x32点阵的其他图标*/ + void Lcd_Display_graphic_32x32(unsigned char page, unsigned char column, unsigned char *dp); + + /*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/ + void Lcd_Display_Graphic_16x16_2(unsigned char reverse,unsigned char page,unsigned char column,unsigned char *dp); + + /*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/ + void Lcd_Display_Graphic_16x16(unsigned char page, unsigned char column, unsigned char *dp, unsigned int wordcount); + + /*显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标*/ + void Lcd_Display_Graphic_8x16(unsigned char page, unsigned char column,unsigned char *dp); + + void Lcd_Display_String_8x16(unsigned int page, unsigned int column, const char *text); + + void Lcd_Display_String_5x8(unsigned int page, unsigned int column, const char *text); + + void display_Selective(int selective); + +}; + +#endif + + diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/Lcd.o b/device/gxx-linux/small_lcd/app_spi_lcd/Lcd.o new file mode 100644 index 0000000..46e9700 Binary files /dev/null and b/device/gxx-linux/small_lcd/app_spi_lcd/Lcd.o differ diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/Makefile b/device/gxx-linux/small_lcd/app_spi_lcd/Makefile new file mode 100644 index 0000000..f720840 --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/Makefile @@ -0,0 +1,22 @@ +objs := main.o Lcd.o DevUtil.o Gpio.o + +smalllcd : $(objs) + g++ -o $@ $^ -lpthread + +# 需要判断是否存在依赖文件 +dep_files := $(foreach f, $(objs), .$(f).d) +dep_files := $(wildcard $(dep_files)) + +# 把依赖文件包含进来 +ifneq ($(dep_files),) + include $(dep_files) +endif + +%.o : %.cpp + g++ -Wp,-MD,.$@.d -c -o $@ $< -lpthread + +clean: + rm *.o biglcd -f + +distclean: + rm $(dep_files) *.o biglcd -f \ No newline at end of file diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/Parameters.h b/device/gxx-linux/small_lcd/app_spi_lcd/Parameters.h new file mode 100644 index 0000000..31e5cce --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/Parameters.h @@ -0,0 +1,102 @@ +#pragma once +#include + +#define Color 3 + +typedef enum Scan_Mode +{ + SM_GRAY, + SM_COLOR +} ScanMode; + +const std::string ScanPaperTypes[] = +{ + + "A4", + "A3" +}; + +const int SPTSizes[] = {1728, 1632}; + +typedef enum Scan_Paper_Type +{ + SPT_A4, + SPT_A3 +}ScanPaperType; + +#ifdef A3 + + // 图像像素值 + #define IMG_HEIGHT 3600 + #define IMG_WIDTH 2592 * 2 + #define SPI_COLOR 0x04501003 //0x0cf01002, 0x04501003 + #define SPI_GRAY 0x0cf01002 + + // 300 dpi 图像宽度像素值(目前仅为双面扫描,故尺寸为单面尺寸乘以2) + #define IMG_WIDTH_300DPI 3672 * 2 + + // 200 dpi 图像宽度像素值(目前仅为双面扫描,故尺寸为单面尺寸乘以2) + #define IMG_WIDTH_200DPI 2448 * 2 + + #define IMG_WIDTH_150DPI 1836 * 2 + + #define IMG_HEIGHT_200DPI IMG_HEIGHT + + #define IMG_HEIGHT_300DPI IMG_HEIGHT * 1.5 + + #define IMG_HEIGHT_150DPI IMG_HEIGHT * 0.75 + + //原始图像相对于200dpi的倍数 + #define IMG_W_RADIO 1 + #define IMG_H_RADIO 1 + #define FRAME_COUNT 4 + + +#else + // 300 dpi 图像宽度像素值(目前仅为双面扫描,故尺寸为单面尺寸乘以2) + +#define IMG_WIDTH_300DPI 2592 * 2 + + // 200 dpi 图像宽度像素值(目前仅为双面扫描,故尺寸为单面尺寸乘以2) +#define IMG_WIDTH_200DPI 1728 * 2 + +#define IMG_WIDTH_150DPI 1296 * 2 + + +#define IMG_HEIGHT_200DPI 3600 + +#define IMG_HEIGHT_300DPI 4050 + +#define IMG_HEIGHT_150DPI 2025 + + //原始图像相对于200dpi 系数 +#define IMG_W_RADIO 1/1.5 +#define IMG_H_RADIO 1 + + // 图像像素值 + + + + +#ifdef HAS_UV +// #define SPI_COLOR 0x03D81001 +// #define SPI_GRAY 0x13001000 + #define SPI_COLOR 0x05181001 + #define SPI_GRAY 0x19501000 +// 0x19501000, 0x05181001 +#else +const int SPI_SP = 0x04b0; +const int SPI_SAMPLE = 256; +const int SPI_COLOR_MODE = SM_COLOR; +const int SCAN_PAPER_TYPE = SPT_A4; +#endif + +const int IMG_HEIGHT = 12000; +const int IMG_V4L_WIDTH = SPTSizes[SCAN_PAPER_TYPE]; +const int FRAME_COUNT = 3; +const int TEST_FRAME = 1; +const int TEST_ENABLE = 0; +const int LED_ENABLE = 1; +const bool SAVE_ENABLE = true; + +#endif diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/filetools.h b/device/gxx-linux/small_lcd/app_spi_lcd/filetools.h new file mode 100644 index 0000000..e9a7c29 --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/filetools.h @@ -0,0 +1,75 @@ +#pragma once +#include +#include +#include +#include +#include + + + +class FileTools +{ +private: + std::string mPath; +public: + FileTools(std::string path){ + mPath = path; + } + void createLog(std::string log) + { + time_t now = time(0); + tm *ltm = localtime(&now); + char loc_date[30]; + sprintf(loc_date, "%d%02d%02d %d:%d:%d", 1900 + ltm->tm_year, 1 + ltm->tm_mon, ltm->tm_mday,ltm->tm_hour, ltm->tm_min, ltm->tm_sec); + std::ofstream ofs(mPath); + ofs << loc_date << ": " << log << std::endl; + ofs.close(); + } + void appendLog(std::string log, bool printTime = true) + { + std::ofstream ofs(mPath, std::ios::app); + if(printTime){ + time_t now = time(0); + tm *ltm = localtime(&now); + char loc_date[30]; + sprintf(loc_date, "%d%02d%02d %d:%d:%d", 1900 + ltm->tm_year, 1 + ltm->tm_mon, ltm->tm_mday,ltm->tm_hour, ltm->tm_min, ltm->tm_sec); + ofs << loc_date << ": " << log << std::endl; + }else{ + ofs << " " << log << std::endl; + } + ofs.close(); + } +}; + + +class StopWatch +{ +public: + StopWatch() { + _start = std::chrono::steady_clock::now(); + } + + void reset() { + _start = std::chrono::steady_clock::now(); + } + + double elapsed_s() { + return std::chrono::duration(std::chrono::steady_clock::now() - _start).count(); + } + + double elapsed_ms() { + return std::chrono::duration(std::chrono::steady_clock::now() - _start).count(); + } + + double elapsed_us() { + return std::chrono::duration(std::chrono::steady_clock::now() - _start).count(); + } + + double elapsed_ns() { + return std::chrono::duration(std::chrono::steady_clock::now() - _start).count(); + } + +private: + std::chrono::steady_clock::time_point _start; +}; + diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/lcd b/device/gxx-linux/small_lcd/app_spi_lcd/lcd new file mode 100644 index 0000000..e5d1bd3 Binary files /dev/null and b/device/gxx-linux/small_lcd/app_spi_lcd/lcd differ diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/main.cpp b/device/gxx-linux/small_lcd/app_spi_lcd/main.cpp new file mode 100644 index 0000000..e6bbc24 --- /dev/null +++ b/device/gxx-linux/small_lcd/app_spi_lcd/main.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include "DevUtil.h" +#include "filetools.h" +#include "Gpio.h" +#include "Lcd.h" + +int main(int argc, char **argv) +{ + Lcd Small_lcd; + Small_lcd.Small_Lcd_Initial_Lcd(); + while(1) + { + //Small_lcd.Lcd_Clear_screen(); + Small_lcd.display_Selective(4); + //sleep(2); + //Small_lcd.Lcd_Clear_screen(); + Small_lcd.display_Selective(1); + //sleep(2); + //Small_lcd.Lcd_Clear_screen(); + Small_lcd.display_Selective(2); + //sleep(2); + //Small_lcd.Lcd_Clear_screen(); + Small_lcd.display_Selective(3); + //sleep(2); + //Small_lcd.Lcd_Clear_screen(); + Small_lcd.display_Selective(1); + //sleep(2); + } + return 0; +} + diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/main.o b/device/gxx-linux/small_lcd/app_spi_lcd/main.o new file mode 100644 index 0000000..88642cb Binary files /dev/null and b/device/gxx-linux/small_lcd/app_spi_lcd/main.o differ diff --git a/device/gxx-linux/small_lcd/app_spi_lcd/smalllcd b/device/gxx-linux/small_lcd/app_spi_lcd/smalllcd new file mode 100644 index 0000000..b5f327d Binary files /dev/null and b/device/gxx-linux/small_lcd/app_spi_lcd/smalllcd differ diff --git a/device/gxx-linux/test.cpp b/device/gxx-linux/test.cpp deleted file mode 100644 index 6d13424..0000000 --- a/device/gxx-linux/test.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define VIDPID_PATH "/opt/camtprd-ffs.sh" - -/* - * FunctionName: main - * Description: - */ -int main(int argc, char *argv[]) -{ - int ret = 0; - printf("argc = %d \n", argc); - if (argc != 3) - { - return -1; - } - unsigned int i_vid = atoi(argv[1]); - unsigned int i_pid = atoi(argv[2]); - printf("arg0 = %d arg1=%d \n", i_vid, i_pid); - char buf_vid[5] ={0}; - char buf_pid[5] ={0}; - buf_vid[4]='\0'; - buf_pid[4]='\0'; - sprintf(buf_vid,"%04x",i_vid); - sprintf(buf_pid,"%04x",i_pid); - printf("buf_vid = %s buf_pid=%s \n", buf_vid, buf_pid); - if (i_pid > 0 && i_vid > 0) - { - FILE *fd; - - fd = fopen(VIDPID_PATH, "rb+"); - if (!fd) { - printf( "error open /usr/local/bin/mtp.sh...\n"); - return -1; - } - else { - printf( "open %s scuess.fd = %d\n", VIDPID_PATH,fd); - } - - /*set vid*/ - fseek(fd , 0x1cb , SEEK_SET); - ret = fwrite(buf_vid, 1, 4, fd); - - /*set pid*/ - fseek(fd , 0x1b3 , SEEK_SET); - ret = fwrite(buf_pid, 1, 4, fd); - - fclose(fd); - return 0; - } - - return -1; -} /* ---------- end of function main ---------- */ diff --git a/device/gxx-linux/testcapimage/main.cpp b/device/gxx-linux/testcapimage/main.cpp index b92c5a3..14056f3 100644 --- a/device/gxx-linux/testcapimage/main.cpp +++ b/device/gxx-linux/testcapimage/main.cpp @@ -8,6 +8,9 @@ #include "config.h" #include "FpgaComm.h" #include "usbservice.h" +#include "MonoCapturer.h" +#include "correct_ultis.h" +#define LOOP_DEBUG static void savebitmap(void *imgdata, int width, int height, bool color, std::string path) { @@ -32,7 +35,7 @@ static void savebitmap(void *imgdata, int width, int height, bool color, std::st std::cout << string_format("split: %d image elapsed:%f ms\n ", i, sw.elapsed_ms()); sw.reset(); - + // if(i == 0) // { // swap(ch_mats[0], ch_mats[2]); @@ -45,7 +48,6 @@ static void savebitmap(void *imgdata, int width, int height, bool color, std::st // swap(ch_mats[1], ch_mats[0]); // } - if (i == 2) { swap(ch_mats[0], ch_mats[2]); @@ -56,7 +58,6 @@ static void savebitmap(void *imgdata, int width, int height, bool color, std::st swap(ch_mats[0], ch_mats[2]); } - cv::merge(ch_mats, saveMat(cv::Rect(mergewidth * i, 0, mergewidth, height))); std::cout << string_format("merge: %d image elapsed:%f ms\n ", i, sw.elapsed_ms()); ch_mats.clear(); @@ -70,32 +71,34 @@ unsigned int delay_done(std::shared_ptr regs, int ms) unsigned int val; unsigned int reg8; regs->read(8, reg8); - std::cout << "reg[8]:" << string_format("0x%08x", reg8) << std::endl; + std::cout << "1 reg[8]:" << string_format("0x%08x", reg8) << std::endl; regs->write(8, reg8 | 0x8); std::cout << "sleep:" << ms << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(ms)); regs->read(8, reg8); - std::cout << "reg[8]:" << string_format("0x%08x", reg8) << std::endl; + std::cout << "1 reg[8]:" << string_format("0x%08x", reg8) << std::endl; regs->read(14, val); + int regv = val; val &= 0x0000ffff; - std::cout << string_format("leight = %d\n", val); + std::cout << string_format("ONE height = %d reg[14] = %d \n", val, regv); regs->write(8, reg8 & 0xfffffff7); std::this_thread::sleep_for(std::chrono::milliseconds(5)); regs->read(14, val); + regv = val; val &= 0x0000ffff; regs->read(8, reg8); - std::cout << "reg[8]:" << string_format("0x%08x", reg8) << std::endl; + 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)); regs->write(8, reg8 | 0x8); regs->read(8, reg8); - std::cout << "reg[8]:" << string_format("0x%08x", reg8) << std::endl; + std::cout << "2 reg[8]:" << string_format("0x%08x", reg8) << std::endl; return val; } -int delaytimes[] = {100, 200, 300, 400}; - -int ws[] = {7344/2, 7344}; +int delaytimes[] = {200, 300, 400, 100, 150}; +int ws[] = {7344 / 2, 7344}; void list_regs(std::shared_ptr regs) { @@ -109,104 +112,217 @@ void list_regs(std::shared_ptr regs) } } +// int main() +// { +// auto cap = std::shared_ptr(new MonoCapturer()); +// StopWatch sw; +// unsigned int val = 0; +// +// auto regs = cap->regs(); +// // UsbService us(regs, nullptr); +// HGScanConfig config; +// config.g200params.color = 0; +// config.g200params.dpi = 3; +// config.g200params.paper = (unsigned int)PaperSize::G400_AUTO; +// void *data; +// // cap->init_autocorrect(0); +// cap->open(config); +// int ch = 0; +// int ixx = 0; +// +// // std::cout << "mod1:" << CV_8UC3 << " " << CV_8UC1 << std::endl; +// +// for (int i = 0; i < 0x10; i++) +// { +// sw.reset(); +// if (regs->read(i, val)) +// std::cout << string_format("reg[%d] = 0x%08x\n", i, val); +// else +// std::cout << "read regs error " << std::endl; +// } +// std::cout << "type enter to grab" << std::endl; +// int ix = 0; +// int width = cap->width(); +// int fixedheight = cap->height(); +// int type = cap->color(); +// int height = fixedheight; +// if (type == CV_8UC3) +// { +// height = fixedheight / 3; +// width = width * 2 * 3 * 3; +// type = CV_8UC1; +// } +// else +// { +// height = fixedheight; +// width = width * 2 * 3; +// } +// +// while ((ch = getchar()) != 'q') +// { +// #ifdef LOOP_DEBUG +// for (int i = 0; i < 2000; i++) +// #endif +// { +// ix++; +// // sw.reset(); +// // for (int j = 0; j < 15; j++) +// // { +// // sw.reset(); +// // if (regs->read(j, val)) +// // std::cout << string_format("reg[%d] = 0x%08x, %f\n", j, val, sw.elapsed_ms()); +// // else +// // std::cout << "read regs error " << std::endl; +// // } +// sw.reset(); +// cap->snap(); +// +// #ifdef LOOP_DEBUG +// height = delay_done(regs, delaytimes[ix % (sizeof(delaytimes) / sizeof(delaytimes[0]))]); +// std::cout << string_format("%dth grab time height = %d", ix, height) << std::endl; +// height = std::min(fixedheight, height); +// #endif +// if (data = cap->readFrame(5000)) +// { +// // for (int i = 0; i < 0x10; i++) +// // { +// // sw.reset(); +// // if (regs->read(i, val)) +// // std::cout << string_format("readFrame reg[%d] = 0x%08x\n", i, val); +// // else +// // std::cout << "read regs error " << std::endl; +// // } +// // std::cout << string_format("QQQQQQQQ %dth grab time height = %d: %fms", ix, height, sw.elapsed_ms()) << std::endl; +// std::cout << string_format("grab time width = %d, height = %d, type = %d: %fms", width, height, type, sw.elapsed_ms()) << std::endl; +// sw.reset(); +// int channel = cap->color() == 16 ? 3 : 1; +// int dstwith = cap->width() * 2 * 3; +// int dstHeight = height; +// cv::Mat mat(dstHeight, dstwith * channel, CV_8UC1, data); +// static int testindex = 0; +// cv::imwrite(std::to_string(++testindex) + std::to_string(dstHeight) + "autosizeorg.jpg", mat); +// #ifndef LOOP_DEBUG +// // cv::Mat mat=GetMergeMat(data,cap->width(),cap->height(),cap->color()); +// // mat = cv::Mat(height, width, type, data); +// // cv::imwrite( std::to_string(ix++)+ ".jpg", mat); +// // std::cout << string_format("%dth grab time height = %d: %fms", ix, height, sw.elapsed_ms()) << std::endl; +// // sw.reset(); +// // savebitmap(data, width, height, true, std::to_string(ix) + ".jpg"); +// // std::cout << string_format("%dth grab save time : %fms", ix, sw.elapsed_ms()) << std::endl; +// // sw.reset(); +// // memset(data, 0, width * height * 3); +// // std::cout << string_format("%dth memset time : %fms", ix, sw.elapsed_ms()) << std::endl; +// #endif +// break; +// } +// else +// { +// std::cout << "error :" << ix << std::endl; +// #ifdef LOOP_DEBUG +// break; +// #endif +// } +// } +// std::cout << "type enter to continue" << std::endl; +// } +// +// return 0; +// } + int main() { - auto cap = std::shared_ptr(new Capturer()); + auto cap = std::shared_ptr(new MonoCapturer()); StopWatch sw; unsigned int val = 0; - auto regs = cap->regs(); - UsbService us(regs, nullptr); - HGScanConfig config; - config.g200params.color=1; - config.g200params.dpi=1; - config.g200params.paper=(unsigned int)PaperSize::G400_A4; - void *data; - // cap->open(config); - cap->open(); - int ch = 0; - int ixx = 0; - - std::cout << "mod1:" << CV_8UC3 << " " << CV_8UC1 << std::endl; - - - for (int i = 0; i < 0x10; i++) - { - sw.reset(); - if (regs->read(i, val)) - std::cout << string_format("reg[%d] = 0x%08x\n", i, val); - else - std::cout << "read regs error " << std::endl; - } - std::cout << "type enter to grab" << std::endl; - int ix = 0; - // int width = cap->width();; - // int fixedheight = cap->height() ; - // int type = cap->color(); - // int height = fixedheight; - // if(type == CV_8UC3) - // { - // height = fixedheight/3; - // width = width*3*3; - // type = CV_8UC1; - // } - // else - // { - // height = fixedheight; - // width = width*3; - // } - - - while ((ch = getchar()) != 'q') + auto regs = cap->regs(); + // UsbService us(regs, nullptr) + int looptimes = 0; + // while ((ch = getchar()) != 'q') { #ifdef LOOP_DEBUG - for (int i = 0; i < 2000; i++) + for (;;) #endif { - ix++; - sw.reset(); - for (int j = 0; j < 15; j++) - { - sw.reset(); - if (regs->read(j, val)) - std::cout << string_format("reg[%d] = 0x%08x, %f\n", j, val, sw.elapsed_ms()); - else - std::cout << "read regs error " << std::endl; - } - cap->snap(); + HGScanConfig config; + config.g200params.color = 0; + config.g200params.dpi = 2; + config.g200params.paper = (unsigned int)PaperSize::G400_AUTO; + void *data; + // cap->init_autocorrect(0); + FPGAConfigParam fpgaparam = GetFpgaparam(config.g200params.dpi, config.g200params.color); + cap->open(config,fpgaparam); + int ch = 0; + int ixx = 0; + unsigned int fpgaversion; + regs->read(15, fpgaversion); + std::cout << "fpgaversion:" << fpgaversion << std::endl; -#ifdef LOOP_DEBUG - height = delay_done(regs, delaytimes[ix % (sizeof(delaytimes) / sizeof(delaytimes[0]))]); - std::cout << string_format("88888%dth grab time height = %d", ix, height) << std::endl; - height = std::min(fixedheight, height); -#endif - if (data = cap->readFrame(3000)) + // for (int i = 0; i < 0x10; i++) + // { + // sw.reset(); + // if (regs->read(i, val)) + // std::cout << string_format("reg[%d] = 0x%08x\n", i, val); + // else + // std::cout << "read regs error " << std::endl; + // } + int ix = 0; + int width = cap->width(); + int fixedheight = cap->height(); + int type = cap->color(); + int height = fixedheight; + if (type == CV_8UC3) { - //std::cout << string_format("%dth grab time height = %d: %fms", ix, height, sw.elapsed_ms()) << std::endl; - //std::cout << string_format("grab time width = %d, height = %d, type = %d: %fms", width, height, type, sw.elapsed_ms()) << std::endl; - -#ifndef LOOP_DEBUG - cv::Mat mat=GetMergeMat(data,cap->width(),cap->height(),cap->color()); - //mat = cv::Mat(height, width, type, data); - cv::imwrite( std::to_string(ix++)+ ".jpg", mat); - //std::cout << string_format("%dth grab time height = %d: %fms", ix, height, sw.elapsed_ms()) << std::endl; - // sw.reset(); - // savebitmap(data, width, height, true, std::to_string(ix) + ".jpg"); - // std::cout << string_format("%dth grab save time : %fms", ix, sw.elapsed_ms()) << std::endl; - // sw.reset(); - // memset(data, 0, width * height * 3); - // std::cout << string_format("%dth memset time : %fms", ix, sw.elapsed_ms()) << std::endl; -#endif + height = fixedheight / 3; + width = width * 2 * 3 * 3; + type = CV_8UC1; } else { - std::cout << "error :" << ix << std::endl; -#ifdef LOOP_DEBUG - break; -#endif + height = fixedheight; + width = width * 2 * 3; } + + for (int i = 0; i < 100; i++) + { + + ix++; + sw.reset(); + cap->snap(); + +#ifdef LOOP_DEBUG + height = delay_done(regs, delaytimes[ix % (sizeof(delaytimes) / sizeof(delaytimes[0]))]); + std::cout << string_format("%dth grab time height = %d", ix, height) << std::endl; + height = std::min(fixedheight, height); +#endif + if (data = cap->readFrame(5000)) + { + std::cout << string_format("grab time width = %d, height = %d, type = %d: %fms", width, height, type, sw.elapsed_ms()) << std::endl; + sw.reset(); + int channel = cap->color() == 16 ? 3 : 1; + int dstwith = cap->width() * 2 * 3; + int dstHeight = height; + cv::Mat mat(dstHeight, dstwith * channel, CV_8UC1, data); + int dstwidth = type==CV_8UC1?width:width/3; + cv::Mat saveMat =GetMergeMat(dstwidth, height, type,mat,0x00090001); + + std::string savepath = std::to_string(++looptimes) + ".bmp"; + cv::imwrite(savepath, saveMat); + //auto smat = MergeImage(channel == 3 ? 1 : 0, mat, dstwith, dstHeight); + //auto ok = cv::imwrite(savepath, smat); + // if (!ok) + // std::cout << "error save file :" << savepath << std::endl; + } + else + { + std::cout << "error :" << ix << std::endl; +#ifdef LOOP_DEBUG + break; +#endif + } + } + cap->close(); } - std::cout << "type enter to continue" << std::endl; } return 0; diff --git a/device/gxx-linux/testdisplay/main.cpp b/device/gxx-linux/testdisplay/main.cpp new file mode 100644 index 0000000..12da96f --- /dev/null +++ b/device/gxx-linux/testdisplay/main.cpp @@ -0,0 +1,18 @@ +#include +#include +#include "MotorController.h" +#include "MenuComponent.h" + +int main() +{ + MotorController mtctrl; + //MenuComponent com; + //com.initmenu(); + //com.select(); + while (1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + return 0; +} \ No newline at end of file diff --git a/device/gxx-linux/testdisplay/xmake.lua b/device/gxx-linux/testdisplay/xmake.lua new file mode 100644 index 0000000..88e2215 --- /dev/null +++ b/device/gxx-linux/testdisplay/xmake.lua @@ -0,0 +1,8 @@ +add_rules("mode.debug", "mode.release") + +target("testdisplay") + set_kind("binary") + add_files("*.cpp") + add_syslinks("pthread") + add_deps("motorcontroller","keymonitor") + add_packages("common") diff --git a/device/gxx-linux/testimgproc/main.cpp b/device/gxx-linux/testimgproc/main.cpp index e49f495..a9c9d29 100644 --- a/device/gxx-linux/testimgproc/main.cpp +++ b/device/gxx-linux/testimgproc/main.cpp @@ -4,10 +4,139 @@ #include "opencv2/opencv.hpp" #include #include "StopWatch.h" - +#include #include "iimageencode.h" #include "imageencode.h" + +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; +} + +void hsvCorrect_init(uint* table) +{ + cv::Mat mat_rgbTable(256 * 256, 256, CV_8UC3); + uchar* ptr_mat_rgbTable = mat_rgbTable.data; + for (size_t r = 0; r < 256; r++) + for (size_t g = 0; g < 256; g++) + for (size_t b = 0; b < 256; b++, ptr_mat_rgbTable += 3) + { + ptr_mat_rgbTable[0] = b; + ptr_mat_rgbTable[1] = g; + ptr_mat_rgbTable[2] = r; + } + + cv::cvtColor(mat_rgbTable, mat_rgbTable, cv::COLOR_BGR2HSV_FULL); + + uchar table_data[256]; + cv::Mat tableLUT(256, 1, CV_8UC1, table_data); + std::vector points_x, points_y, coefficient; + points_x = { 0, 80, 175, 255 }; + points_y = { 12, 85, 175, 270 }; + coefficient = caculate(points_x, points_y); + for (int j = 0; j < 256; j++) + table_data[j] = static_cast(cv::max(0.0, coefficient[0] * j * j * j + coefficient[1] * j * j + coefficient[2] * j + coefficient[3])); + + cv::Mat hsv_ms[3]; + cv::split(mat_rgbTable, hsv_ms); + cv::LUT(hsv_ms[0], tableLUT, hsv_ms[0]); + cv::merge(hsv_ms, 3, mat_rgbTable); + + cv::cvtColor(mat_rgbTable, mat_rgbTable, cv::COLOR_HSV2BGR_FULL); + + cv::Mat mat_bgr32(256, 256 * 256, CV_8UC4); + cv::cvtColor(mat_rgbTable, mat_bgr32, cv::COLOR_BGR2BGRA); + + memcpy(table, mat_bgr32.data, mat_bgr32.total() * sizeof(uint)); +} + +void hsvCorrect(cv::Mat& image, uint* table) +{ + if (image.channels() != 3) + return; + + cv::Mat bgra; + cv::cvtColor(image, bgra, cv::COLOR_BGR2BGRA); + uint* ptr = bgra.ptr(); + int rows = bgra.rows, cols = bgra.cols; + for (int i = 0; i < rows; i++) + { + ptr = reinterpret_cast(bgra.ptr(i)); + for (int j = 0; j < cols; j++) + ptr[j] = table[ptr[j] & 0x00ffffff]; + } + cv::cvtColor(bgra, image, cv::COLOR_BGRA2BGR); +} + static std::string read_all_from(std::string path) { int t; @@ -26,16 +155,20 @@ 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 = "/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"<encode(mat); return 0; } \ No newline at end of file diff --git a/device/gxx-linux/testkeymonitor/main.cpp b/device/gxx-linux/testkeymonitor/main.cpp new file mode 100644 index 0000000..989986c --- /dev/null +++ b/device/gxx-linux/testkeymonitor/main.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include "keymonitor.h" +#include "uartregsaccess.h" +#include "config.h" +#include "DisplayCenter.h" +#include "MenuComponent.h" +int main() +{ + MenuComponent m_menu; + m_menu.initmenu(); + auto displayCenter = std::shared_ptr(new DisplayCenter()); + displayCenter->PutMsg(DisType::Dis_Welcome, 0,ClearScreen::All); + displayCenter->PutMsg(DisType::Dis_Idel, 0,ClearScreen::All); + auto motorregs = std::shared_ptr(new UartRegsAccess(MOTOR_UART, 921600, 0x07, 0x87)); + auto keycall = [&](int keyvalye) + { + // std::cout << "keycallback keyvalue= " << keyvalye << std::endl; + // auto key = (KeyMonitor::HGKey)(keyvalye); + // switch (key) + // { + // case KeyMonitor::HGKey::Key_Enter: + // displayCenter->PutMsg(DisType::Dis_Err_AqrImgTimeout, 0); + // break; + // case KeyMonitor::HGKey::Key_Cancle: + // displayCenter->PutMsg(DisType::Dis_Idel, 0); + // break; + // case KeyMonitor::HGKey::Key_Count: + // displayCenter->PutMsg(DisType::Dis_Count_Page, 0); + // break; + // case KeyMonitor::HGKey::Key_Handle: + // displayCenter->PutMsg(DisType::Dis_Err_HandModeJam, 0); + // break; + // case KeyMonitor::HGKey::Key_DoubleFeed: + // displayCenter->PutMsg(DisType::Dis_Err_DoubleFeed, 0); + // break; + // case KeyMonitor::HGKey::Key_Left: + // displayCenter->PutMsg(DisType::Dis_Set_PollPI_Low, 0); + // break; + // case KeyMonitor::HGKey::Key_Menu: + // displayCenter->PutMsg(DisType::Dis_Set_PollPI_Mid, 0); + // break; + // case KeyMonitor::HGKey::Key_Right: + // displayCenter->PutMsg(DisType::Dis_Set_PollPI_High, 0); + // break; + // case KeyMonitor::HGKey::Key_Clear: + // displayCenter->PutMsg(DisType::Dis_Err_PaperScrew, 0); + // break; + // default: + // break; + // } + printf("keyvalue %d ",keyvalye); + m_menu.option(keyvalye); + displayCenter->PutMsg(m_menu.getcurtype(),0,ClearScreen::All); + motorregs->write(0x6, 128); + motorregs->write(0x6, 0); + }; + KeyMonitor monitor(keycall); + while (1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + return 0; +} \ No newline at end of file diff --git a/device/gxx-linux/testkeymonitor/xmake.lua b/device/gxx-linux/testkeymonitor/xmake.lua new file mode 100644 index 0000000..aaea5ac --- /dev/null +++ b/device/gxx-linux/testkeymonitor/xmake.lua @@ -0,0 +1,7 @@ +add_rules("mode.debug", "mode.release") + +target("testkeymonitor") + set_kind("binary") + add_files("*.cpp") + add_deps("keymonitor","regs","conf","display","motorcontroller") + add_packages("common") diff --git a/device/gxx-linux/testlcd/main.cpp b/device/gxx-linux/testlcd/main.cpp new file mode 100644 index 0000000..518296e --- /dev/null +++ b/device/gxx-linux/testlcd/main.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include "DisplayCenter.h" +#include "LCDDisplay.h" +#include + +using namespace std; +std::vector vcdistype={ + DisType::Dis_Init,//启动欢迎界面 + DisType::Dis_Welcome, + DisType::Dis_Idel,//就绪 + DisType::Dis_Set_ClearPaperPass, + DisType::Dis_Set_Count, + DisType::Dis_Err_DoubleFeed, + DisType::Dis_Err_Stable, + DisType::Dis_Err_CoverOpen, + DisType::Dis_Err_JamIn, + DisType::Dis_Err_JamOut, + DisType::Dis_Err_HandModeJam, + DisType::Dis_Err_PaperScrew, + DisType::Dis_Err_FeedError, + DisType::Dis_Err_AqrImgTimeout, + DisType::Dis_Set_PollPaperIntensity, + DisType::Dis_Set_PollPI_High, + DisType::Dis_Set_PollPI_Mid, + DisType::Dis_Set_PollPI_Low, + DisType::Dis_Count_Page, + DisType::Dis_Scan_Page, + DisType::Dis_Device_Lock +}; +int main() +{ + cout << "********** testlcd **********" << endl; + uint64_t cout =0; + LCDDisplay lcd; + while (1) + { + //for (size_t i = 0; i < vcdistype.size(); i++) + { + //lcd.PutMsg(vcdistype[i],i,ClearScreen::All); + //std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + lcd.DisplayState(DisType::Dis_Count_Page,cout++,ClearScreen::All); + std::cout <<"**********"<< cout<<"**********"<< endl; + } + + return 0; +} \ No newline at end of file diff --git a/device/gxx-linux/testlcd/xmake.lua b/device/gxx-linux/testlcd/xmake.lua new file mode 100644 index 0000000..d7cc322 --- /dev/null +++ b/device/gxx-linux/testlcd/xmake.lua @@ -0,0 +1,7 @@ +add_rules("mode.debug", "mode.release") + +target("testlcd") + set_kind("binary") + add_files("*.cpp") + add_packages("common") + add_deps("display") \ No newline at end of file diff --git a/device/gxx-linux/testmotorboard/main.cpp b/device/gxx-linux/testmotorboard/main.cpp index f71b48f..b9ce8a0 100644 --- a/device/gxx-linux/testmotorboard/main.cpp +++ b/device/gxx-linux/testmotorboard/main.cpp @@ -10,6 +10,7 @@ #include "uartregsaccess.h" #include "Gpio.h" #include "StopWatch.h" +#include "wakeup.hpp" using namespace std; @@ -39,7 +40,14 @@ int main() { FileTools ft("/home/linaro/regs.log"); ft.clear(); - MotorBoard mb; + WakeUp wake; + MotorBoard mb(nullptr); + wake.setinitcallback([&mb]{ + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + mb.init_statecontrol(); + },[&mb]{ + mb.release_statecontrol(); + }); unsigned int val = 0; //GpioOut gpio(151); bool exit = false; @@ -52,8 +60,9 @@ int main() case 0: exit = true; break; - case 1:{ - mb.start(); + case 1: + { + mb.start({0}); break; } case 2: @@ -62,9 +71,42 @@ int main() case 3: mb.clear_error(); break; - case 4: - mb.pick_paper(); + case 4:{ + { + int size = 20; + std::cin >> size; + for(int x = 0;x< size;x++){ + mb.pick_paper(); + if(x > 20 && ((x%21) == 0) ) + { + wake.power_off(); + this_thread::sleep_for(chrono::seconds(5)); + wake.power_on(); + this_thread::sleep_for(chrono::seconds(5)); + for (int i = 0; i < 8; i++) + { + StopWatch sw; + // gpio.setValue(Gpio::Low); + // gpio.setValue(Gpio::High); + if (mb.read(i, val)) + { + // gpio.setValue(Gpio::Low); + std::cout << string_format("read : %f\n", sw.elapsed_ms()); + std::cout << hex; + std::cout << "reg[0x" << i << "] =0x" << setw(8) << setfill('0') << val << std::endl; + } + else + { + std::cout << "read regs error " << std::endl; + } + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + std::cout << "send == "<< x << std::endl; + } + } break; + } case 5: { for (int i = 0; i < 8; i++) @@ -110,30 +152,49 @@ int main() printf("motorboard callback mb_osmode_call changed"); }; - MotorBoardGlue mb_glue = {mb_error_call, mb_scandone_call, mb_osmode_call,nullptr,nullptr,nullptr}; + auto mb_set_sleeptime_call = [&](unsigned int speedmode) + { + printf("\n mb_set_sleeptime_call val= %d ", speedmode); + }; + MotorBoardGlue mb_glue = {mb_error_call, mb_scandone_call, mb_osmode_call, mb_set_sleeptime_call,nullptr,nullptr,nullptr}; mb.set_callbacks(mb_glue); done_scan = 0; - mb.start(); - mb.set_speed_mode(1, 200, 1); + mb.SetKeyState(true); + unsigned int reg0; + mb.read(0x00, reg0); + SMBCONFIG *smb_config = (SMBCONFIG *)®0; + smb_config->dpi_mode = 0; + mb.write(0x00, reg0); + mb.set_speed_mode(2); + mb.clear_error(); + //mb.set_cuospeed(41); + mb.start({0}); + mb.pick_paper(); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); StopWatch sw; + int num = 0; for (;;) { - if (mb.wait_paper_out(3000)) + if (mb.wait_paper_in(1000)) { // std::this_thread::sleep_for(std::chrono::milliseconds(100)); - std::cout << __func__ << " call: paper pick" << std::endl; - mb.pick_paper(); - sw.reset(); + std::cout << __func__ << " call: paper pick num = "<< num++ << std::endl; + //std::this_thread::sleep_for(std::chrono::milliseconds(1000));//simulate capture + if(mb.wait_paper_out(1000)) + { + std::cout << __func__ << " call: paper out stop snap " < 3) - done_scan = -2; - } + //else + // { + // if (sw.elapsed_s() > 3) + // done_scan = -2; + // } + mb.pick_paper(); } std::cout << __func__ << " call: exit" << std::endl; } diff --git a/device/gxx-linux/testscanner/main.cpp b/device/gxx-linux/testscanner/main.cpp index a34ccbe..200e369 100644 --- a/device/gxx-linux/testscanner/main.cpp +++ b/device/gxx-linux/testscanner/main.cpp @@ -4,8 +4,11 @@ #include "scannerregs.h" #include "usbservice.h" #include "motorboard.h" +#include "ICapturer.h" #include "Capturer.h" +#include "MonoCapturer.h" #include "imageusbhandler.h" +#include "CImageMerge.h" using namespace std; int menu() { @@ -16,6 +19,7 @@ int menu() { cout << "(2) stop. " << endl; cout << "(3) count. " << endl; cout << "(4) mode. " << endl; + cout << "(5) testcorrect"<> choice; @@ -25,10 +29,15 @@ int menu() { int main() { + // auto img = cv::imread("/home/linaro/anlogic_gxx_linux/0_org.jpg",cv::IMREAD_GRAYSCALE); + // auto retmat = CImageMerge().MergeImage(true,img,7776,150,0x90001); + // img.release(); + // cv::imwrite("/home/linaro/anlogic_gxx_linux/0_org_t.jpg",retmat); + // return 1; bool exit = false; - std::shared_ptr motorboard(new MotorBoard()); - std::shared_ptr capturer(new Capturer()); - std::shared_ptr scanner(new Scanner(capturer, motorboard,nullptr)); + std::shared_ptr motorboard(new MotorBoard(nullptr)); + std::shared_ptr capturer(new MonoCapturer()); + std::shared_ptr scanner(new Scanner(capturer, motorboard,nullptr)); std::shared_ptr scannerRegs(new ScannerRegAccess(scanner)); scanner->set_imagehandler(std::shared_ptr(new ImageUsbHandler())); int option; @@ -41,7 +50,25 @@ int main() exit = true; break; case 1: + HGScanConfig cfg;//={ + cfg.g200params.paper = 16; + cfg.g200params.color=0; + cfg.g200params.dpi = 0x02; + cfg.g200params.double_feed_enbale=0; + cfg.g200params.stable_enbale = 0; + cfg.g200params.screw_detect_enable = 0; + cfg.g200params.screw_detect_level = 0; + cfg.g200params.iscorrect_mode = 0; + cfg.g200params.en_autosize = 0; + cfg.g200params.pc_correct=0; + cfg.g200params.enable_sizecheck = 0; + cfg.g200params.enabledsp_cache = 0; + cfg.g200params.sizeerror_errorratio = 0; + //}; + scanner->configparam(cfg); scanner->start_scan(); + while(1) + std::this_thread::sleep_for(chrono::milliseconds(1)); break; case 2: scanner->stop_scan(); @@ -51,6 +78,8 @@ int main() break; case 4: std::cout << "os mode" << scanner->mode() << std::endl; + case 5 : + scanner->test_autocorrect(0); default: cout << "nop, Please select again! " << endl; break; diff --git a/device/gxx-linux/testthread b/device/gxx-linux/testthread new file mode 100644 index 0000000..dc719b7 Binary files /dev/null and b/device/gxx-linux/testthread differ diff --git a/device/gxx-linux/testusb/main.cpp b/device/gxx-linux/testusb/main.cpp index 2e3fb99..c0010fd 100644 --- a/device/gxx-linux/testusb/main.cpp +++ b/device/gxx-linux/testusb/main.cpp @@ -33,119 +33,83 @@ int menu() cout << "(2) clear notify. " << endl; cout << "(3/4) autocorrect " << endl; cout << "(5) color mode change test " << endl; - cout << "(6) clear screen " << endl; cout << "(0) Quit. " << endl << endl; cout << ": "; cin >> choice; - if(choice == 6) - system("clear"); - return choice; } int main() { + auto cap = std::shared_ptr(new Capturer()); + auto mt = std::shared_ptr(new MotorBoard(nullptr)); + auto scanner = std::shared_ptr(new Scanner(cap, mt,nullptr)); + UsbService us(cap->regs(), mt->regs()); + auto notify = us.notify(); + std::shared_ptr usbImage(new UsbImageProcQueue(notify)); + auto transfer = us.transmiter(); + std::shared_ptr regs = std::shared_ptr(new ScannerRegAccess(scanner, usbImage, transfer)); + scanner->set_imagehandler(std::shared_ptr(new ImageUsbHandler(usbImage))); + us.set_scannerregs(regs); + unsigned int val = 0; + bool exit = false; + int option = 0; + unsigned char data[116] = {0x00}; + int count = 0; + + // auto mem = std::shared_ptr(new VectorMemroy()); + // mem->resize(10); + // memcpy(mem->data(),data,sizeof(data)); + for (;;) { - auto cap = std::shared_ptr(new Capturer()); - auto mt = std::shared_ptr(new MotorBoard()); - auto scanner = std::shared_ptr(new Scanner(cap, mt,nullptr)); - UsbService us(cap->regs(), mt->regs()); - auto notify = us.notify(); - std::shared_ptr usbImage(new UsbImageProcQueue(notify)); - auto transfer = us.transmiter(); - std::shared_ptr regs = std::shared_ptr(new ScannerRegAccess(scanner, usbImage, transfer)); - scanner->set_imagehandler(std::shared_ptr(new ImageUsbHandler(usbImage))); - us.set_scannerregs(regs); - unsigned int val = 0; - bool exit = false; - int option = 0; - unsigned char data[116] = {0x00}; - int count = 0; - - - //* - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - for(;;) + option = menu(); + switch (option) { - if(menu() == 0) - break; + case 0: + exit = true; + break; + case 1: + this_thread::sleep_for(chrono::milliseconds(1)); + break; + case 2: + notify->clear(); + break; + case 3: + // { + // auto nread= transfer->read_bulk(data,sizeof(data)); + // break; + // } + case 4: + scanner->test_autocorrect(option==3); + break; + case 5: + { + + HGScanConfig config = {0}; + for (size_t i = 0; i < 40; i++) + { + std::string msg=(i % 2 == 0?" mode COLOR ":" mode GRAY "); + std::cout << "Test color mode change index = "<test_cap(config); + this_thread::sleep_for(chrono::milliseconds(1)); + } + std::cout << "Please select again! " << std::endl; + break; } - transfer.reset(); - /*/ - while(1) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - ///////*//// - - return 0; + default: + std::cout << "Please select again! " << std::endl; + break; + } + /* code */ + if (exit) + break; } - // auto cap = std::shared_ptr(new Capturer()); - // auto mt = std::shared_ptr(new MotorBoard()); - // auto scanner = std::shared_ptr(new Scanner(cap, mt,nullptr)); - // UsbService us(cap->regs(), mt->regs()); - // auto notify = us.notify(); - // std::shared_ptr usbImage(new UsbImageProcQueue(notify)); - // auto transfer = us.transmiter(); - // std::shared_ptr regs = std::shared_ptr(new ScannerRegAccess(scanner, usbImage, transfer)); - // scanner->set_imagehandler(std::shared_ptr(new ImageUsbHandler(usbImage))); - // us.set_scannerregs(regs); - // unsigned int val = 0; - // bool exit = false; - // int option = 0; - // unsigned char data[116] = {0x00}; - // int count = 0; - - // // auto mem = std::shared_ptr(new VectorMemroy()); - // // mem->resize(10); - // // memcpy(mem->data(),data,sizeof(data)); - // for (;;) - // { - // option = menu(); - // switch (option) - // { - // case 0: - // exit = true; - // break; - // case 1: - // this_thread::sleep_for(chrono::milliseconds(1)); - // break; - // case 2: - // notify->clear(); - // break; - // case 3: - // // { - // // auto nread= transfer->read_bulk(data,sizeof(data)); - // // break; - // // } - // case 4: - // scanner->test_autocorrect(option==3); - // break; - // case 5: - // { - - // HGScanConfig config = {0}; - // for (size_t i = 0; i < 40; i++) - // { - // std::string msg=(i % 2 == 0?" mode COLOR ":" mode GRAY "); - // std::cout << "Test color mode change index = "<test_cap(config); - // this_thread::sleep_for(chrono::milliseconds(1)); - // } - // std::cout << "Please select again! " << std::endl; - // break; - // } - // default: - // std::cout << "Please select again! " << std::endl; - // break; - // } - // /* code */ - // if (exit) - // break; - // } std::cout << "exit munu" << std::endl; diff --git a/device/gxx-linux/testusb/usb-rk3399/inc/buildconf.h b/device/gxx-linux/testusb/usb-rk3399/inc/buildconf.h deleted file mode 100644 index 88ff97f..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/inc/buildconf.h +++ /dev/null @@ -1,12 +0,0 @@ -#define _LARGEFILE64_SOURCE -#define _FILE_OFFSET_BITS 64 - -//#define CONFIG_USB_NON_BLOCKING_WRITE 1 - -#define CONFIG_USB_FS_SUPPORT 1 // USB 1.1 Full speed -#define CONFIG_USB_HS_SUPPORT 1 // USB 2.0 High speed -#define CONFIG_USB_SS_SUPPORT 1 // USB 3.0 SuperSpeed - -#define CONFIG_READ_FILE_BUFFER_SIZE (1024*1024) // Must be a 2^x value. -#define CONFIG_MAX_TX_USB_BUFFER_SIZE (16*512) // Must be a multiple of 512 and be less than CONFIG_READ_FILE_BUFFER_SIZE -#define CONFIG_MAX_RX_USB_BUFFER_SIZE (16*512) // Must be a multiple of 512 \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/inc/camtp.h b/device/gxx-linux/testusb/usb-rk3399/inc/camtp.h deleted file mode 100644 index 9602676..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/inc/camtp.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * CAMTP Responder - * Copyright (c) 2020 Holdtecs Technologies - * - * CAMTP Responder is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * CAMTP Responder is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 3 for more details. - * - * You should have received a copy of the GNU General Public License - * along with CAMTP Responder; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file camtp.h - * @brief Main CAMMTP protocol functions. - * @author Barry Ruan - */ - -#ifndef _INC_CAMTP_H_ -#define _INC_CAMTP_H_ - -#define MAX_STORAGE_NB 16 -#define MAX_CFG_STRING_SIZE 512 - -#pragma pack() -typedef struct mtp_usb_cfg_ -{ - uint16_t usb_vendor_id; - uint16_t usb_product_id; - uint8_t usb_class; - uint8_t usb_subclass; - uint8_t usb_protocol; - uint16_t usb_dev_version; - uint16_t usb_max_packet_size; - uint8_t usb_functionfs_mode; - - char usb_device_path[MAX_CFG_STRING_SIZE + 1]; - char usb_endpoint_in[MAX_CFG_STRING_SIZE + 1]; - char usb_endpoint_out[MAX_CFG_STRING_SIZE + 1]; - char usb_endpoint_intin[MAX_CFG_STRING_SIZE + 1]; - - char usb_string_manufacturer[MAX_CFG_STRING_SIZE + 1]; - char usb_string_product[MAX_CFG_STRING_SIZE + 1]; - char usb_string_serial[MAX_CFG_STRING_SIZE + 1]; - char usb_string_version[MAX_CFG_STRING_SIZE + 1]; - - char usb_string_interface[MAX_CFG_STRING_SIZE + 1]; - - int wait_connection; - int loop_on_disconnect; - - int show_hidden_files; - - int val_umask; - -}camtp_usb_cfg; - - -typedef struct camtp_ctx_ -{ - uint32_t session_id; - - camtp_usb_cfg usb_cfg; - - void * usb_ctx; - - volatile int cancel_req; - -}camtp_ctx; - -int camtp_load_config_file(camtp_ctx * context, const char * conffile); - -#endif \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/inc/default_cfg.h b/device/gxx-linux/testusb/usb-rk3399/inc/default_cfg.h deleted file mode 100644 index 8030c5d..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/inc/default_cfg.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * CAMTP Responder - * Copyright (c) 2020 Holdtecs Technologies - * - * CAMTP Responder is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * CAMTP Responder is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 3 for more details. - * - * You should have received a copy of the GNU General Public License - * along with CAMTP Responder; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file default.h - * @brief Main CAMMTP protocol functions. - * @author Barry Ruan - */ - -#ifndef _INC_DEFAULT_CFG_H_ -#define _INC_DEFAULT_CFG_H_ - -#ifndef CAMTPR_CONF_FILE -#define CAMTPR_CONF_FILE "/etc/camtprd/camtprd.conf" -#endif - -#define MAX_PACKET_SIZE 1024 - -#define USB_DEV_VENDOR_ID 0x04b4 -//0x04B4 // Linux Foundation -#define USB_DEV_PRODUCT_ID 0x8613 // PTP Gadget - -#define USB_DEV_CLASS 0x6 // Still Imaging device -#define USB_DEV_SUBCLASS 0x0 // -#define USB_DEV_PROTOCOL 0x0 // - -#define USB_DEV_VERSION 0x3008 - -#define USB_FFS_MODE 1 - -#define USB_DEV "/dev/ffs-camtp/ep0" - -#define USB_EPIN "/dev/ffs-camtp/ep1" -#define USB_EPOUT "/dev/ffs-camtp/ep2" -#define USB_EPINTIN "/dev/ffs-camtp/ep3" - -#define MANUFACTURER "HUAGAO Technologies" -#define PRODUCT "HUAGAO" -#define SERIALNUMBER "01234567ABCDEFG" - -#endif diff --git a/device/gxx-linux/testusb/usb-rk3399/inc/logs_out.h b/device/gxx-linux/testusb/usb-rk3399/inc/logs_out.h deleted file mode 100644 index 57a33ff..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/inc/logs_out.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * CAMTP Responder - * Copyright (c) 2020 Holdtecs Technologies - * - * CAMTP Responder is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * CAMTP Responder is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 3 for more details. - * - * You should have received a copy of the GNU General Public License - * along with CAMTP Responder; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file logs_out.h - * @brief Log output functions - * @author *** - */ - -#ifndef _INC_DEBUG_OUT_H_ -#define _INC_DEBUG_OUT_H_ -#include "stringex.hpp" -#include "applog.h" - -#define RUN_TEST - -const std::string loggername = "camtprd"; - -void timestamp(char * timestr, int maxsize); - -#define SIZEHEX PRIx64 -#define DEBUG -#ifdef USE_SYSLOG - -#include - -#else - -#ifdef DEBUG -#include -#endif - -#endif - -#if defined(WIN32) || defined(RUN_TEST) - -#define PRINT_DEBUG printf -#define PRINT_ERROR printf -#define PRINT_MSG - -#elif defined(USE_SYSLOG) // Syslog usage - -#define PRINT_MSG(fmt, args...) syslog(LOG_NOTICE, "[CAMTPrd - Info] " fmt "\n", \ - ## args) -#define PRINT_ERROR(fmt, args...) syslog(LOG_ERR, "[CAMTPrd - Error] " fmt "\n", \ - ## args) -#define PRINT_WARN(fmt, args...) syslog(LOG_WARNING, "[CAMTPrd - Warning] " fmt "\n", \ - ## args) -#ifdef DEBUG - -#define PRINT_DEBUG(fmt, args...) syslog(LOG_DEBUG, "[CAMTPrd - Debug] " fmt "\n", \ - ## args) -#else - -#define PRINT_DEBUG(fmt, args...) - -#endif - -#else // Stdout usage - -// #define PRINT_MSG(fmt, args...) { \ -// char timestr[32]; \ -// timestamp((char*)×tr, sizeof(timestr)); \ -// fprintf(stdout, \ -// "[CAMTPrd - %s - Info] " fmt "\n",(char*)×tr, \ -// ## args); \ -// fflush(stdout); \ -// } - -#define PRINT_MSG(fmt, args...) { \ - char timestr[32]; \ - timestamp((char*)×tr, sizeof(timestr)); \ - LOG_INFO(string_format("[CAMTPrd - %s - Info] " fmt "\n",(char*)×tr, ## args)); \ - } - - -#define PRINT_ERROR(fmt, args...) { \ - char timestr[32]; \ - timestamp((char*)×tr, sizeof(timestr)); \ - LOG_ERROR(string_format("[CAMTPrd - %s - Info] " fmt "\n",(char*)×tr, ## args)); \ - } - -#define PRINT_WARN(fmt, args...) { \ - char timestr[32]; \ - timestamp((char*)×tr, sizeof(timestr)); \ - LOG_WARN(string_format("[CAMTPrd - %s - Info] " fmt "\n",(char*)×tr, ## args)); \ - } - -#ifdef DEBUG -#define PRINT_DEBUG(fmt, args...) { \ - char timestr[32]; \ - timestamp((char*)×tr, sizeof(timestr)); \ - LOG_DEBUG(string_format("[CAMTPrd - %s - Info] " fmt "\n",(char*)×tr, ## args)); \ - } -#else - -#define PRINT_DEBUG(fmt, args...) - -#endif - -#endif - -#ifdef DEBUG - -#define PRINT_DEBUG_BUF(x, y) printbuf( x, y ); -void printbuf(void * buf,int size); - -#else - -#define PRINT_DEBUG_BUF(x, y) - -#endif - -#endif - diff --git a/device/gxx-linux/testusb/usb-rk3399/inc/usb_gadget.h b/device/gxx-linux/testusb/usb-rk3399/inc/usb_gadget.h deleted file mode 100644 index 171b86f..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/inc/usb_gadget.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * CAMTP Responder - * Copyright (c) 2020 Holdtecs Technologies - * - * CAMTP Responder is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * CAMTP Responder is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 3 for more details. - * - * You should have received a copy of the GNU General Public License - * along with CAMTP Responder; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file usb_gadget.c - * @brief USB gadget layer - * @author *** - */ - -#ifndef _INC_USB_GADGET_H_ -#define _INC_USB_GADGET_H_ - -#include -#include -#include - -#include "usbstring.h" - -enum -{ - EP_DESCRIPTOR_IN = 0, - EP_DESCRIPTOR_OUT, - EP_DESCRIPTOR_INT_IN, - - EP_NB_OF_DESCRIPTORS -}; - -#define EP_INT_MODE 0x00000000 -#define EP_BULK_MODE 0x00000001 -#define EP_IN_DIR 0x00000000 -#define EP_OUT_DIR 0x00000002 -#define EP_HS_MODE 0x00000004 -#define EP_SS_MODE 0x00000008 - -typedef struct _EndPointsDesc { - struct usb_interface_descriptor if_desc; - struct usb_endpoint_descriptor_no_audio ep_desc_in; - struct usb_endpoint_descriptor_no_audio ep_desc_out; - struct usb_endpoint_descriptor_no_audio ep_desc_int_in; -} __attribute__((packed)) EndPointsDesc; - -typedef struct _SSEndPointsDesc { - struct usb_interface_descriptor if_desc; - struct usb_endpoint_descriptor_no_audio ep_desc_in; - struct usb_ss_ep_comp_descriptor ep_desc_in_comp; - struct usb_endpoint_descriptor_no_audio ep_desc_out; - struct usb_ss_ep_comp_descriptor ep_desc_out_comp; - struct usb_endpoint_descriptor_no_audio ep_desc_int_in; - struct usb_ss_ep_comp_descriptor ep_desc_int_in_comp; - -} __attribute__((packed)) SSEndPointsDesc; - -typedef struct ep_cfg_descriptor { - struct usb_endpoint_descriptor_no_audio ep_desc; -#ifdef CONFIG_USB_SS_SUPPORT - struct usb_ss_ep_comp_descriptor ep_desc_comp; -#endif -} __attribute__((packed)) ep_cfg_descriptor; - -// Direct GadgetFS mode -typedef struct _usb_cfg -{ - uint32_t head; - -#if CONFIG_USB_FS_SUPPORT - struct usb_config_descriptor cfg_fs; - EndPointsDesc ep_desc_fs; -#endif - -#if CONFIG_USB_HS_SUPPORT - struct usb_config_descriptor cfg_hs; - EndPointsDesc ep_desc_hs; -#endif - -#if CONFIG_USB_SS_SUPPORT - struct usb_config_descriptor cfg_ss; - SSEndPointsDesc ep_desc_ss; -#endif - - struct usb_device_descriptor dev_desc; - -} __attribute__ ((packed)) usb_cfg; - -// FunctionFS mode -typedef struct _usb_ffs_cfg -{ - uint32_t magic; - uint32_t length; -#ifndef OLD_FUNCTIONFS_DESCRIPTORS // Kernel > v3.14 - uint32_t flags; -#endif - -#ifdef CONFIG_USB_FS_SUPPORT - uint32_t fs_count; -#endif - -#ifdef CONFIG_USB_HS_SUPPORT - uint32_t hs_count; -#endif - -#if defined(CONFIG_USB_SS_SUPPORT) && !defined(OLD_FUNCTIONFS_DESCRIPTORS) - uint32_t ss_count; -#endif - -#ifdef CONFIG_USB_FS_SUPPORT - EndPointsDesc ep_desc_fs; -#endif - -#ifdef CONFIG_USB_HS_SUPPORT - EndPointsDesc ep_desc_hs; -#endif - -#if defined(CONFIG_USB_SS_SUPPORT) && !defined(OLD_FUNCTIONFS_DESCRIPTORS) - SSEndPointsDesc ep_desc_ss; -#endif - -} __attribute__ ((packed)) usb_ffs_cfg; - -typedef struct _ffs_strings -{ - struct usb_functionfs_strings_head header; - uint16_t code; - char string_data[128]; // string data. -} __attribute__((packed)) ffs_strings; - -typedef struct _ep_cfg -{ - uint32_t head; - - ep_cfg_descriptor ep_desc[2]; - -} __attribute__ ((packed)) ep_cfg; - -enum { - STRINGID_MANUFACTURER = 1, - STRINGID_PRODUCT, - STRINGID_SERIAL, - STRINGID_CONFIG_HS, - STRINGID_CONFIG_LS, - STRINGID_INTERFACE, - STRINGID_MAX -}; - -#define MAX_USB_STRING 16 - -typedef struct _usb_gadget -{ - int usb_device; - - usb_cfg * usb_config; - usb_ffs_cfg * usb_ffs_config; - - ep_cfg * ep_config[3]; - - int ep_handles[EP_NB_OF_DESCRIPTORS]; - - char * ep_path[3]; - - int stop; - - struct usb_string stringtab[MAX_USB_STRING]; - - int wait_connection; - pthread_t thread; - int thread_not_started; - -}usb_gadget; - -#endif diff --git a/device/gxx-linux/testusb/usb-rk3399/inc/usbdevice.h b/device/gxx-linux/testusb/usb-rk3399/inc/usbdevice.h deleted file mode 100644 index 19ce3a0..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/inc/usbdevice.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include "camtp.h" -#include "buildconf.h" -#include "usb_gadget.h" - -#include "usb_io.h" - -#define ASYNC_EP - -class UsbDevice -{ - async_usb_gadget *usb_; - -#ifdef ASYNC_EP - dyn_mem_ptr unhandled_ep0(struct usb_functionfs_event* pev); - dyn_mem_ptr handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - - std::map> dispatcher_; - dyn_mem_ptr handle_packet_heart_beat(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_packet_invalid(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_packet_get_setting(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_packet_set_setting(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - - void do_system_command(const char* cmd); -#endif - -public: - UsbDevice(std::function handler = std::function(), - std::function call_back = std::function()); - virtual ~UsbDevice(); - - int read_bulk(void* data, int size, int* err = nullptr, bool full = true); - int write_bulk(void* data, int size, int* err = nullptr); - int write_int(void* data, int size, int* err = nullptr); - - void abort_int(); - - bool is_connected() - { - return b_connected; - } - -private: - void usb_main(); - - usb_gadget * init_usb_camtp_gadget(camtp_ctx * ctx); - void deinit_usb_camtp_gadget(usb_gadget * usbctx); - - int handle_ffs_ep0(usb_gadget * ctx); - int handle_ep0(usb_gadget * ctx); - int add_usb_string(usb_gadget * usbctx, int id, char * string); - void fill_ep_descriptor(camtp_ctx * ctx, usb_gadget * usbctx,struct usb_endpoint_descriptor_no_audio * desc,int index,unsigned int flags); - void fill_if_descriptor(camtp_ctx * ctx, usb_gadget * usbctx, struct usb_interface_descriptor * desc); - void fill_config_descriptor(camtp_ctx * ctx , usb_gadget * usbctx,struct usb_config_descriptor * desc,int total_size, int hs); - void fill_dev_descriptor(camtp_ctx * ctx, usb_gadget * usbctx,struct usb_device_descriptor * desc); - - void handle_setup_request(usb_gadget * ctx, struct usb_ctrlrequest* setup); - int init_eps(usb_gadget * ctx, int ffs_mode, bool open_ep = true); - int init_ep(usb_gadget * ctx,int index,int ffs_mode, bool open_ep = true); - int write(int fd, void* data, size_t size, int* err = nullptr); - int read(int fd, void* data, size_t size, int* err = nullptr, bool full = true); - - int dispatch_ep0(struct usb_functionfs_event *ev, size_t len); - - static const int cacheSize; - std::shared_ptr camtp_context; - usb_gadget gadget; - std::function ctrl_handler; - std::function connect_call; - std::thread thread_main; - usb_gadget *usb_ctx; - volatile bool b_connected; - - friend class ep_waiter; -}; \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/inc/usbstring.h b/device/gxx-linux/testusb/usb-rk3399/inc/usbstring.h deleted file mode 100644 index da2dff5..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/inc/usbstring.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * CAMTP Responder - * Copyright (c) 2020 Holdtecs Technologies - * - * CAMTP Responder is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * CAMTP Responder is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 3 for more details. - * - * You should have received a copy of the GNU General Public License - * along with CAMTP Responder; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - /** - * @file usbstring.h - * @brief USB strings - Function & structures declarations. - * @author *** - */ - -#ifndef _INC_USBSTRING_H_ -#define _INC_USBSTRING_H_ - -struct usb_string { - uint8_t id; - char *str; -}; - -struct usb_gadget_strings { - uint16_t language; /* 0x0409 for en-us */ - struct usb_string *strings; -}; - -int usb_gadget_get_string (struct usb_gadget_strings *table, int id, uint8_t *buf); -int unicode2charstring(char * str, uint16_t * unicodestr, int maxstrsize); -int char2unicodestring(char * unicodestr, int index, int maxsize, char * str, int unicodestrsize); -#endif diff --git a/device/gxx-linux/testusb/usb-rk3399/inotify.h b/device/gxx-linux/testusb/usb-rk3399/inotify.h deleted file mode 100644 index c97b9a9..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/inotify.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include - -class INotify -{ - public: - virtual ~INotify(){} - - virtual void notify(void* data, int size) = 0; - virtual void clear() = 0; -}; - -typedef std::shared_ptr NotifyPtr; \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/ireceive.h b/device/gxx-linux/testusb/usb-rk3399/ireceive.h deleted file mode 100644 index d662947..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/ireceive.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "imgproc.h" -#include "imemory.h" - -class UsbDevice; -class ThreadEx; - -class IReceive -{ -public: - virtual ~IReceive(){} - - virtual int read(MemoryPtr& memroy) = 0; - virtual int read_bulk(void* data,unsigned int length) = 0; - virtual bool is_reading() = 0; - virtual void cannel() = 0; -}; \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/itransmit.h b/device/gxx-linux/testusb/usb-rk3399/itransmit.h deleted file mode 100644 index c3f19c2..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/itransmit.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "imemory.h" - -class ITransmit -{ -public: - virtual ~ITransmit(){} - virtual int write_bulk(void* data,int size) = 0; - virtual void write(MemoryPtr memroy) = 0; - virtual bool is_writing() = 0; - virtual void cannel() = 0; -}; \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/CMakeLists.txt b/device/gxx-linux/testusb/usb-rk3399/src/common/CMakeLists.txt deleted file mode 100644 index 466b700..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -project(common) -add_compile_options(-std=c++11) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") -aux_source_directory(${PROJECT_SOURCE_DIR} DIR_SRCS) -file(GLOB DIR_HEADS "${PROJECT_SOURCE_DIR}/*" "${PROJECT_SOURCE_DIR}/json/*") -set(DIR_SRCS ${DIR_SRCS} ${DIR_HEADS}) -add_library(${PROJECT_NAME} STATIC ${DIR_SRCS}) - -target_link_libraries(${PROJECT_NAME} PRIVATE - dl - pthread - rt - ) -target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR} - ) -set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../scanner/build/) diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/cmd.cpp b/device/gxx-linux/testusb/usb-rk3399/src/common/cmd.cpp deleted file mode 100644 index d8abf93..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/cmd.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "cmd.h" - - - - -namespace parser -{ - static void command_line_to_arguments(const char* cmdl, std::vector& args) - { - while(*cmdl) - { - const char* h = cmdl; - while(*h == ' ' || *h == '\t') - h++; - if(*h == 0) - break; - - cmdl = h; - if(*h == '\"') - { - cmdl++; - h++; - while(*h) - { - if(*h == '\"') - break; - if(*h == '\\') - h++; - h++; - } - } - else - { - while(*h) - { - if(*h == ' ' || *h == '\t') - break; - h++; - } - } - if(h > cmdl) - args.push_back(std::string(cmdl, h - cmdl)); - else if(*h == '\"') - args.push_back(""); - - if(*h == 0) - break; - - cmdl = h + 1; - } - } -} - - - - -cmd_line::cmd_line() -{} -cmd_line::~cmd_line() -{} - -cmd_line* cmd_line::from_console(const char* tips) -{ - std::string in(""); - char ch = 0; - - if(!tips || *tips == 0) - tips = "input"; - - printf("%s%s>%s", CONSOLE_COLOR_FRONT_BLUE, tips, CONSOLE_COLOR_NONE); - while((ch = getchar()) != '\n') - in.append(1, ch); - - return cmd_line::from_command_line(in.c_str()); -} -cmd_line* cmd_line::from_command_line(const char* cmdl) -{ - cmd_line* cmd = new cmd_line(); - - cmd->cmd_line_ = cmdl; - parser::command_line_to_arguments(cmdl, cmd->arguments_); - - return cmd; -} - -size_t cmd_line::count(void) -{ - return arguments_.size(); -} -const char* cmd_line::parameter(int ind) -{ - if(ind >= 0 && ind < arguments_.size()) - return arguments_[ind].c_str(); - else - return nullptr; -} -const char* cmd_line::parameter(const char* key) -{ - for(int i = 0; i < arguments_.size() - 1; ++i) - { - if(arguments_[i] == key) - return arguments_[i + 1].c_str(); - } - - return nullptr; -} diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/cmd.h b/device/gxx-linux/testusb/usb-rk3399/src/common/cmd.h deleted file mode 100644 index 91a65c3..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/cmd.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -// command line utility -// -// created on 2023-02-10 -// - -#include "referer.h" -#include -#include - -#define CONSOLE_COLOR_NONE "\033[0m" -#define CONSOLE_COLOR_FRONT_BLACK "\033[0;30m" -#define CONSOLE_COLOR_FRONT_DARK_GRAY "\033[1;30m" -#define CONSOLE_COLOR_FRONT_RED "\033[0;31m" -#define CONSOLE_COLOR_FRONT_LIGHT_RED "\033[1;31m" -#define CONSOLE_COLOR_FRONT_GREEN "\033[0;32m" -#define CONSOLE_COLOR_FRONT_LIGHT_GREEN "\033[1;32m" -#define CONSOLE_COLOR_FRONT_BROWN "\033[0;33m" -#define CONSOLE_COLOR_FRONT_YELLOW "\033[1;33m" -#define CONSOLE_COLOR_FRONT_BLUE "\033[0;34m" -#define CONSOLE_COLOR_FRONT_LIGHT_BLUE "\033[1;34m" -#define CONSOLE_COLOR_FRONT_PURPLE "\033[0;35m" -#define CONSOLE_COLOR_FRONT_LIGHT_PURPLE "\033[1;35m" -#define CONSOLE_COLOR_FRONT_CYAN "\033[0;36m" -#define CONSOLE_COLOR_FRONT_LIGHT_CYAN "\033[1;36m" -#define CONSOLE_COLOR_FRONT_LIGHT_GRAY "\033[0;37m" -#define CONSOLE_COLOR_FRONT_WHITE "\033[1;37m" - -#define CONSOLE_COLOR_BACK_BLACK "\033[0;40m" -#define CONSOLE_COLOR_BACK_DARK_GRAY "\033[1;40m" -#define CONSOLE_COLOR_BACK_RED "\033[0;41m" -#define CONSOLE_COLOR_BACK_LIGHT_RED "\033[1;41m" -#define CONSOLE_COLOR_BACK_GREEN "\033[0;42m" -#define CONSOLE_COLOR_BACK_LIGHT_GREEN "\033[1;42m" -#define CONSOLE_COLOR_BACK_BROWN "\033[0;43m" -#define CONSOLE_COLOR_BACK_YELLOW "\033[1;43m" -#define CONSOLE_COLOR_BACK_BLUE "\033[0;44m" -#define CONSOLE_COLOR_BACK_LIGHT_BLUE "\033[1;44m" -#define CONSOLE_COLOR_BACK_PURPLE "\033[0;45m" -#define CONSOLE_COLOR_BACK_LIGHT_PURPLE "\033[1;45m" -#define CONSOLE_COLOR_BACK_CYAN "\033[0;46m" -#define CONSOLE_COLOR_BACK_LIGHT_CYAN "\033[1;46m" -#define CONSOLE_COLOR_BACK_LIGHT_GRAY "\033[0;47m" -#define CONSOLE_COLOR_BACK_WHITE "\033[1;47m" - - -namespace console -{ - // special effects: - // \033[0m close all attributes - // \033[1m set high-light - // \033[4m underline - // \033[5m blink - // \033[7m reverse(反显) - // \033[8m blanking(消隐) - // \033[30m -- \033[37m set foreground color - // \033[40m -- \033[47m set background color - // - // cursor position: - // \033[nA move up n lines - // \033[nB move down n lines - // \033[nC move right n cols - // \033[nD move left n cols - // \033[y;xH set cursor position - // \033[2J clear screen - // \033[K clear the line after cursor position - // \033[s save cursor position - // \033[u restore cursor position - // \033[?25l hide cursor - // \033[?25h show cursor -}; - -class cmd_line : public refer -{ - std::string cmd_line_; - std::vector arguments_; - -protected: - cmd_line(); - ~cmd_line(); - -public: - static cmd_line* from_console(const char* tips); - static cmd_line* from_command_line(const char* cmdl); - -public: - size_t count(void); - const char* parameter(int ind); - const char* parameter(const char* key); -}; - diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/data.cpp b/device/gxx-linux/testusb/usb-rk3399/src/common/data.cpp deleted file mode 100644 index f524ea4..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/data.cpp +++ /dev/null @@ -1,466 +0,0 @@ -#include "data.h" - - -#include - -#if defined(WIN32) || defined(_WIN64) -#include - -namespace sys_util -{ - int get_disk_size(const char* path, uint64_t* total, uint64_t* avail, uint64_t* blocksize) - { - std::string disk(path); - size_t pos = disk.find("\\"); - DWORD spc = 0, bps = 0, avc = 0, tot = 0; - - if (pos++ != std::string::npos) - disk.erase(pos); - if (GetDiskFreeSpaceA(disk.c_str(), &spc, &bps, &avc, &tot)) - { - if (total) - { - *total = tot; - *total *= bps * spc; - } - if (avail) - { - *avail = avc; - *avail *= bps * spc; - } - if (blocksize) - { - *blocksize = bps; - *blocksize *= spc; - } - - return 0; - } - else - { - return GetLastError(); - } - } -} -#else -#include "sys_util.h" -#include -#include -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -packet_data_base::packet_data_base() : pack_cmd_(0), pack_id_(0) - , progress_notify_(PROGRESS_NOTIFYER()) -{} -packet_data_base::~packet_data_base() -{} - -int packet_data_base::notify_progress(uint64_t total, uint64_t cur_size, uint32_t err) -{ - if (progress_notify_) - progress_notify_(total, cur_size, err); - else - return ENOENT; -} - -void packet_data_base::set_packet_param(uint32_t cmd, uint32_t id) -{ - pack_cmd_ = cmd; - pack_id_ = id; -} -int packet_data_base::get_packet_command(void) -{ - return pack_cmd_; -} -int packet_data_base::get_packet_id(void) -{ - return pack_id_; -} - -void packet_data_base::set_progress_notify(PROGRESS_NOTIFYER notify) -{ - progress_notify_ = notify; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -data_holder::data_holder() -{} -data_holder::~data_holder() -{} - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -empty_holer::empty_holer(uint64_t size) : size_(size), put_(0) -{} -empty_holer::~empty_holer() -{} - -int empty_holer::put_data(const void* data, uint32_t* size) -{ - if (*size >= size_ - put_) - { - *size -= size_ - put_; - put_ = size_; - } - else - { - put_ += *size; - } - notify_progress(size_, put_, 0); - - return 0; -} -bool empty_holer::is_complete(void) -{ - return size_ == put_; -} -uint32_t empty_holer::get_required(void) -{ - return size_ - put_; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -file_saver::file_saver(void) : size_(0), wrote_(0), path_(""), check_(""), dst_(nullptr), pack_cmd_(0), pack_id_(0) -{} -file_saver::~file_saver() -{ - close(); -} - -void file_saver::close(void) -{ - if(dst_) - fclose(dst_); - dst_ = nullptr; - - size_ = wrote_ = pack_cmd_ = pack_id_ = 0; - path_ = check_ = ""; -} - -int file_saver::open(const char* path, uint64_t size, const char* check) -{ - int err = 0; - - close(); - dst_ = fopen(path, "wb"); - if(dst_) - { - uint64_t space = 0; - - err = sys_util::get_disk_size(path, nullptr, &space, nullptr); - if (err || space < size * 1.5) - { - fclose(dst_); - dst_ = nullptr; - remove(path); - if (err == 0) - err = ENOSPC; - } - else - { - path_ = path; - size_ = size; - check_ = check ? check : ""; - } - } - else - { - err = errno; - } - - return err; -} - -int file_saver::put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) -{ - if(!dst_) - return ENOENT; - - int w = *size > size_ - wrote_ ? size_ - wrote_ : *size, - real_w = fwrite(data, 1, w, dst_), // should handle error here ! - err = 0; - - *size = real_w; - wrote_ += real_w; - if(wrote_ >= size_) - { - fclose(dst_); - dst_ = nullptr; - } - else if (real_w < w) // what happens ? - { - err = ferror(dst_); - } - notify_progress(size_, wrote_, err); - - return 0; -} -bool file_saver::is_complete(void) -{ - return wrote_ >= size_; -} -uint32_t file_saver::get_required(void) -{ - return size_ - wrote_; -} - - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -data_source::data_source() -{} -data_source::~data_source() -{} - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// dyn_mem -uint64_t dyn_mem::mem_used_bytes_ = 0; -MUTEX dyn_mem::mem_lock_; - - dyn_mem::dyn_mem(size_t size) : buf_(nullptr), len_(0), space_(ALIGN_INT(size, 16)) - { - buf_ = (uint8_t*)malloc(space_); - if(buf_) - { - LOCKER l(dyn_mem::mem_lock_); - dyn_mem::mem_used_bytes_ += space_; - memset(buf_, 0, space_); - } - } - dyn_mem::dyn_mem(void* buf, size_t size) : buf_((uint8_t*)buf), space_(size), len_(size) - { - - } - -dyn_mem::~dyn_mem() -{ - if(buf_) - { - free(buf_); - { - LOCKER l(dyn_mem::mem_lock_); - dyn_mem::mem_used_bytes_ -= space_; - } - } -} - -uint64_t dyn_mem::mem_used(void) -{ - return dyn_mem::mem_used_bytes_; -} - dyn_mem_ptr dyn_mem::memory(size_t size) - { - return new dyn_mem(size); - } - -uint32_t dyn_mem::space(void) -{ - return space_; -} -bool dyn_mem::set_len(size_t len) -{ - if(len > space_) - return false; - - len_ = len; - - return true; -} -int dyn_mem::put(const void* data, int len) -{ - if(len + len_ > space_) - len = space_ - len; - - if(len > 0) - { - memcpy(buf_ + len_, data, len); - len_ += len; - } - else - len = 0; - - return len; -} -void* dyn_mem::detach(size_t* size) -{ - void* buf = buf_; - - if (size) - *size = space_; - space_ = len_ = 0; - buf_ = nullptr; - - return buf; -} - -size_t dyn_mem::used(size_t len) -{ - if(len >= len_) - { - len_ = 0; - } - else if(len) - { - memcpy(buf_, buf_ + len, len_ - len); - len_ -= len; - } - - return len_; -} -dyn_mem& dyn_mem::operator+=(dyn_mem& r) -{ - if(len_ + r.get_rest() > space_) - { - size_t size = ALIGN_INT(len_ + r.get_rest(), 16); - uint8_t *buf = (uint8_t*)malloc(size); - memcpy(buf, buf_, len_); - free(buf_); - buf_ = buf; - { - LOCKER l(dyn_mem::mem_lock_); - dyn_mem::mem_used_bytes_ += size - space_; - } - space_ = size; - } - memcpy(buf_ + len_, r.buf_, r.get_rest()); - len_ += r.get_rest(); - - return *this; -} - -bool dyn_mem::is_memory_block(void) -{ - return true; -} -uint32_t dyn_mem::get_rest(void) -{ - return len_; -} - -// following API valid when is_memory_block() return true -uint8_t* dyn_mem::ptr(void) -{ - return buf_; -} - -// following API valid when is_memory_block() return false -int dyn_mem::fetch_data(void* buf, uint32_t* size) -{ - if(*size >= len_) - { - memcpy(buf, buf_, len_); - *size = len_; - len_ = 0; - } - else - { - memcpy(buf, buf_, *size); - used(*size); - } - - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -file_reader::file_reader() : len_(0), src_(nullptr), path_(""), consume_(0) -{} -file_reader::~file_reader() -{ - if(src_) - fclose(src_); -} - -int file_reader::open(const char* file) -{ - if(src_) - fclose(src_); - - src_ = fopen(file, "rb"); - if(!src_) - return errno; - - FSEEK(src_, 0, SEEK_END); - len_ = FTELL(src_); - FSEEK(src_, 0, SEEK_SET); - path_ = file; - consume_ = 0; - - return 0; -} -int file_reader::attach(FILE* f) -{ - if (src_) - { - fclose(src_); - src_ = nullptr; - } - - uint64_t cur = FTELL(f); - - FSEEK(f, 0, SEEK_END); - len_ = FTELL(f); - FSEEK(f, cur, SEEK_SET); - if (len_ <= cur) - return EINVAL; - - src_ = f; - len_ -= cur; - consume_ = 0; - - return 0; -} -FILE* file_reader::detach(void) -{ - FILE* ret = src_; - - src_ = nullptr; - len_ = 0; - path_ = ""; - - return ret; -} - -bool file_reader::is_memory_block(void) -{ - return false; -} -uint32_t file_reader::get_rest(void) -{ - return len_ - consume_; -} - -// following API valid when is_memory_block() return true -uint8_t* file_reader::ptr(void) -{ - return nullptr; -} - -// following API valid when is_memory_block() return false -int file_reader::fetch_data(void* buf, uint32_t* size) -{ - if (!src_) - return ENODATA; - - size_t r = fread(buf, 1, *size, src_); // fix me if ERROR occurs !!! - - consume_ += r; - *size = r; - if (consume_ >= len_) - { - fclose(src_); - src_ = nullptr; - } - notify_progress(len_, consume_, 0); - - return 0; -} diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/data.h b/device/gxx-linux/testusb/usb-rk3399/src/common/data.h deleted file mode 100644 index 53fc191..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/data.h +++ /dev/null @@ -1,232 +0,0 @@ -#pragma once - -// Objects IO -// -// created on 2023-03-10 - -#include "referer.h" -#include "packet.h" - -#include -#include - -#define CLS_PTR(cls) typedef cls* cls##_ptr; - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -/* packet parameter keeper, parameter of corresponding packet -*/ -#define PROGRESS_NOTIFYER std::function - -class packet_data_base : public refer -{ - PROGRESS_NOTIFYER progress_notify_; - -protected: - uint32_t pack_cmd_; - uint32_t pack_id_; - -public: - packet_data_base(); - -protected: - virtual ~packet_data_base(); - int notify_progress(uint64_t total, uint64_t cur_size, uint32_t err); - -public: - void set_packet_param(uint32_t cmd, uint32_t id); - int get_packet_command(void); - int get_packet_id(void); - - void set_progress_notify(PROGRESS_NOTIFYER notify = PROGRESS_NOTIFYER()); -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -/* data_holder, used when data is also required for a certain packet -*/ -class data_holder : public packet_data_base -{ -public: - data_holder(); -protected: - virtual ~data_holder(); - -public: - virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) = 0; // return error code - virtual bool is_complete(void) = 0; - virtual uint32_t get_required(void) = 0; -}; - -class empty_holer : public data_holder -{ - uint64_t size_; - uint64_t put_; - -public: - empty_holer(uint64_t size); -protected: - ~empty_holer(); - - -public: - virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override; // return error code - virtual bool is_complete(void) override; - virtual uint32_t get_required(void) override; -}; - -class file_saver : public data_holder -{ - uint64_t size_; - uint64_t wrote_; - std::string path_; - std::string check_; - FILE *dst_; - uint32_t pack_cmd_; - uint32_t pack_id_; - - void close(void); - -public: - file_saver(void); -protected: - ~file_saver(); - -public: - int open(const char* path, uint64_t size, const char* check = nullptr); - -public: - virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override; - virtual bool is_complete(void) override; - virtual uint32_t get_required(void) override; -}; - - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -/* data_source, can be a memory block or STREAM object -*/ -class data_source : public packet_data_base -{ - uint32_t pack_cmd_; - uint32_t pack_id_; - -public: - data_source(); - -protected: - virtual ~data_source(); - -public: - virtual bool is_memory_block(void) = 0; - virtual uint32_t get_rest(void) = 0; - - // following API valid when is_memory_block() return true - virtual uint8_t* ptr(void) = 0; - - // following API valid when is_memory_block() return false. return error code - virtual int fetch_data(void* buf, uint32_t* size) = 0; -}; - - -class dyn_mem : public data_source -{ - uint8_t* buf_; // data buf - size_t space_; // occupy space in bytes - size_t len_; // data length in bytes - - static MUTEX mem_lock_; - static uint64_t mem_used_bytes_; - -public: - dyn_mem(size_t size); - dyn_mem(void* buf, size_t size); - - static uint64_t mem_used(void); - static dyn_mem* memory(size_t size); - -protected: - ~dyn_mem(); - -public: - uint32_t space(void); - bool set_len(size_t len); - int put(const void* data, int len); - void* detach(size_t* size); // for constructed from dyn_mem(void* buf, size_t size) - - size_t used(size_t len); // used len bytes content, move following data to head and set data length, return rest data length - dyn_mem& operator+=(dyn_mem& r); - -public: - virtual bool is_memory_block(void) override; - virtual uint32_t get_rest(void) override; - - // following API valid when is_memory_block() return true - virtual uint8_t* ptr(void) override; - - // following API valid when is_memory_block() return false - virtual int fetch_data(void* buf, uint32_t* size) override; -}; - -class file_reader : public data_source -{ - size_t len_; - size_t consume_; - FILE *src_; - std::string path_; - -public: - file_reader(); - -protected: - ~file_reader(); - -public: - int open(const char* file); - int attach(FILE* f); - FILE* detach(void); - -public: - virtual bool is_memory_block(void) override; - virtual uint32_t get_rest(void) override; - - // following API valid when is_memory_block() return true - virtual uint8_t* ptr(void) override; - - // following API valid when is_memory_block() return false - virtual int fetch_data(void* buf, uint32_t* size) override; -}; - -CLS_PTR(packet_data_base); -CLS_PTR(data_holder); -CLS_PTR(data_source); -CLS_PTR(dyn_mem); -CLS_PTR(file_reader); - - -// callback proto -// -// parameters: usb_functionfs_event* - the function event ptr -// -// dyn_mem_ptr - the packet buffer, read-only -// -// uint32_t* - to return how many data in bytes the handler consumed -// -// normally, the value should be PACK_BASE::payload_len, i.e. the handler consume all data of an entire packet -// -// when invalid packet, suggest use the entire data -// -// packet_data_base_ptr* - return data_holder or data_source or nullptr -// -// data_holder: the packet/command need more data than dyn_mem_ptr provides to complete the business. such as 'write a large file' -// -// data_source: the reply content may be a large data (a large file content) -// -// return value of all routines is the reply packet, nullptr if the packet need not reply -// -#define FUNCTION_PROTO_COMMAND_HANDLE dyn_mem_ptr(dyn_mem_ptr, uint32_t* /*used*/, packet_data_base_ptr* /*The number of bytes required for this packet, 0 is over for this packet*/) - diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/event_monitor.cpp b/device/gxx-linux/testusb/usb-rk3399/src/common/event_monitor.cpp deleted file mode 100644 index 657f3b1..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/event_monitor.cpp +++ /dev/null @@ -1,257 +0,0 @@ -#include "event_monitor.h" - -// #define __USE_GNU // for gettid of including file 'bits/unistd_ext.h' - -#include /* nonblocking */ -#include /*setrlimit */ -#include -#include -#include -#include -#include -#include -// #include // for gettid -#include -#include -#include - -#include "log_util.h" - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// event_handler -event_handler::event_handler() -{} -event_handler::~event_handler() -{} - - - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// parent_holder -parent_holder::parent_holder() -{} -parent_holder::~parent_holder() -{} - - - - - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// linux - epoll wrapper ... -class epoll_wrapper : public event_monitor -{ - int32_t epoll_fd_; - int32_t quit_fd_[2]; - volatile bool run_; - std::vector threads_; - - static int32_t epoll_max; - - void clear_threads(void) - { - if(threads_.size()) - { - for (size_t i = 0; i < threads_.size(); ++i) - { - if (threads_[i]->joinable()) - threads_[i]->join(); - threads_[i].reset(); - } - threads_.clear(); - } - } - void close_monitor_fd(void) - { - if (epoll_fd_ != -1) - close(epoll_fd_); - epoll_fd_ = -1; - } - void clear(void) - { - clear_threads(); - close_monitor_fd(); - } - void monitor_thread(void) - { - log_cls::log(LOG_LEVEL_DEBUG, "monitor thread(%p) of object(%p) is working ...\n", gettid(), this); - while (run_) - { - struct epoll_event evs; - - memset(&evs, 0, sizeof(evs)); - if (epoll_wait(epoll_fd_, &evs, 1, -1) == -1) - continue; - if (evs.events == EPOLLOUT && evs.data.fd == quit_fd_[1]) - break; - - if (evs.events == EPOLLIN) - ((event_handler*)evs.data.ptr)->on_event(event_handler::EVENT_READ, nullptr, 0); - else if (evs.events == EPOLLOUT) - ((event_handler*)evs.data.ptr)->on_event(event_handler::EVENT_WRITE, nullptr, 0); - else - ; - } - log_cls::log(LOG_LEVEL_DEBUG, "monitor thread(%p) of object(%p) finished working.\n", gettid(), this); - } - -protected: - virtual ~epoll_wrapper() - { - stop(); - } - -public: - epoll_wrapper(const char* desc) : event_monitor(desc), epoll_fd_(-1), run_(true) - { - memset(quit_fd_, -1, sizeof(quit_fd_)); - } - -public: - virtual int32_t start(int32_t threads = 1) override - { - int32_t ret = stop(); - struct rlimit rt; - - rt.rlim_max = rt.rlim_cur = epoll_wrapper::epoll_max; - if (ret == 0 && setrlimit(RLIMIT_NOFILE, &rt) == 0) - { - epoll_fd_ = epoll_create(epoll_wrapper::epoll_max); - if (epoll_fd_ == -1) - { - ret = errno; - log_cls::log(LOG_LEVEL_FATAL, "epoll_create for '%s' failed: %s\n", desc_.c_str(), strerror(ret)); - } - else - { - run_ = true; - for (size_t i = 0; i < (size_t)threads; ++i) - { - THREAD_PTR t;//(new std::thread(&epoll_wrapper::monitor_thread, this)); - t.reset(new std::thread(&epoll_wrapper::monitor_thread, this)); - threads_.push_back(t); - } - } - } - else - { - log_cls::log(LOG_LEVEL_FATAL, "setrlimit for '%s-epoll' failed: %s\n", desc_.c_str(), strerror(ret)); - } - - return ret; - } - virtual int32_t stop(void) override - { - if(threads_.size()) - { - struct epoll_event ev; - #ifdef __USE_GNU - pipe2(quit_fd_, O_NONBLOCK); - #else - pipe(quit_fd_); - #endif - - log_cls::log(LOG_LEVEL_DEBUG, "quit fd[0] = %p, fd[1] = %p\n", quit_fd_[0], quit_fd_[1]); - - run_ = false; - ev.data.fd = quit_fd_[1]; - ev.events = EPOLLOUT | EPOLLET | EPOLLONESHOT; - for(size_t i = 0; i < threads_.size(); ++i) - epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, ev.data.fd, &ev); - clear_threads(); - close(quit_fd_[0]); - close(quit_fd_[1]); - memset(quit_fd_, -1, sizeof(quit_fd_)); - } - - close_monitor_fd(); - - return 0; - } - - virtual int32_t add_fd(event_handler* handler) override - { - struct epoll_event ev; - int32_t ret = -1; - - if (!handler || handler->get_fd() == -1) - return EINVAL; - - if (epoll_fd_ == -1) - return EFAULT; - - handler->add_ref(); // add ref for epoll_event holder ... - ev.data.ptr = handler; - ev.events = EPOLLIN | EPOLLOUT | EPOLLET; // EPOLLONESHOT | EPOLLHUP - ret = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, handler->get_fd(), &ev); - if (ret == -1) - { - ret = errno; - log_cls::log(LOG_LEVEL_FATAL, "add fd(%d) to %s-epoll failed: %s\n", handler->get_fd(), desc_.c_str(), strerror(ret)); - handler->release(); - } - - return ret; - } - virtual int32_t remove_fd(event_handler* handler) override - { - struct epoll_event ev; - int32_t ret = -1; - - if (!handler || handler->get_fd() == -1) - return EINVAL; - - if (epoll_fd_ == -1) - return EFAULT; - - ev.data.ptr = handler; - ev.events = EPOLLIN | EPOLLOUT | EPOLLET | EPOLLHUP; // EPOLLONESHOT - ret = epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, handler->get_fd(), &ev); - - if (ret == 0) - { - // ENOENT returned if object 'handler' has not registered, so we can free it here when success in EPOLL_CTL_DEL ... - handler->release(); - } - else - { - ret = errno; - log_cls::log(LOG_LEVEL_FATAL, "remove fd(%d) from %s-epoll failed: %s\n", handler->get_fd(), desc_.c_str(), strerror(ret)); - } - - return ret; - } -}; -int32_t epoll_wrapper::epoll_max = 100; - - - - - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// event_handler -event_monitor::event_monitor(const char* desc) : desc_(desc ? desc : "") -{ - log_cls::log(LOG_LEVEL_DEBUG, "+event_monitor(%p) of '%s' contructing ...\n", this, desc_.c_str()); -} -event_monitor::~event_monitor() -{ - log_cls::log(LOG_LEVEL_DEBUG, "-event_monitor(%p) of '%s' destroyed\n", this, desc_.c_str()); -} - -event_monitor* event_monitor::create(const char* desc, int32_t type) -{ - if (type == EV_TYPE_EPOLL) - return dynamic_cast(new epoll_wrapper(desc)); - else - return nullptr; -} diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/event_monitor.h b/device/gxx-linux/testusb/usb-rk3399/src/common/event_monitor.h deleted file mode 100644 index 2a77a29..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/event_monitor.h +++ /dev/null @@ -1,153 +0,0 @@ -#pragma once - -// event monitor -// -// created on 2022-11-29 -// - -#include "referer.h" -#include "packet.h" - -#include -#include - -typedef std::shared_ptr THREAD_PTR; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// event definition ... -enum scanner_event -{ - SCANNER_EVENT_NONE = 0, - - // 1 - IPC - SCANNER_EVENT_IPC_DATA_RECEIVED = 1, - SCANNER_EVENT_IPC_DATA_SENT, - - // 2 - image-collector - SCANNER_EVENT_COLLECTOR_WORKING = 100, // on_event(, nullptr, 0), the first message after start success - - // normal image, double feeding image, jammed image, stapled imge, size-check error image ... - SCANNER_EVENT_COLLECTOR_IMG_DATA, // on_event(, (LPIMGD)data, bytes of data), image data transfer, buffer can be re-used when return - - SCANNER_EVENT_COLLECTOR_PAPER_ON, // on_event(, (bool*)paper_on, (bool)local_display) - SCANNER_EVENT_COLLECTOR_COVER_OPENNED, // on_event(, (bool*)openned, (bool)local_display) - SCANNER_EVENT_COLLECTOR_SLEEPPING, // on_event(, (bool*)sleepping, (bool)local_display) - SCANNER_EVENT_COLLECTOR_ERROR, // on_event(, (char*)err-msg, (bool)local_display), used when unknown fatal error occurs! - - SCANNER_EVENT_COLLECTOR_STOPPED, // on_event(, (char*)err-msg, (size_t)err-code), the last message after start success - - // 3 - image-process - SCANNER_EVENT_IMAGE_PROC_FINAL_BUF = 200, // on_event(, (void**)buf, (size_t)len), get buffer for store the final image - SCANNER_EVENT_IMAGE_PROC_OK, // on_event(, ) - SCANNER_EVENT_IMAGE_PROC_ERR, - - // 4 - resource - SCANNER_EVENT_RESOURCE_LOW_MEM = 300, // on_event(, (bool*)low_mem, (bool)local_display) - SCANNER_EVENT_RESOURCE_LOW_DISK, // on_event(, (bool*)low_disk, (bool)local_display) - SCANNER_EVENT_RESOURCE_HIGH_CPU, // on_event(, (bool*)high_cpu, (bool)local_display) -}; - -typedef struct _img_data -{ - LPPACKIMAGE info; - uint8_t* data; -}IMGD, *LPIMGD; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// object event_handler -// -// derived from 'event_handler' if your class will handle some events of drived by events -// -class event_handler : public refer -{ -protected: - event_handler(); - virtual ~event_handler(); - -public: - virtual int32_t on_event(int32_t ev, void* data, size_t data_len) = 0; - virtual int32_t get_fd(void) = 0; - - enum - { - EVENT_READ = 0, - EVENT_WRITE, - }; -}; - -class parent_holder : public refer -{ -protected: - parent_holder(); - virtual ~parent_holder(); - -public: - virtual int32_t stop(void) = 0; // stop work and release parent ptr -}; - -// event_monitor to manage an event-driven model, this will trigger EVENT_READ/EVENT_WRITE events to 'handler' -// -class event_monitor : public refer -{ -protected: - std::string desc_; - -protected: - event_monitor(const char* desc); - virtual ~event_monitor(); - -public: - virtual int32_t start(int32_t threads = 1) = 0; - virtual int32_t stop(void) = 0; - - virtual int32_t add_fd(event_handler* handler) = 0; - virtual int32_t remove_fd(event_handler* handler) = 0; - - enum - { - EV_TYPE_POLL = 1, - EV_TYPE_EPOLL, - }; - static event_monitor* create(const char* desc, int32_t type = EV_TYPE_EPOLL); -}; - -class sane_cfg_provider : public refer -{ -public: - sane_cfg_provider() - {} - virtual ~sane_cfg_provider() - {} - -public: - // Function: get all or given name configuration value - // - // Parameters: buf - to receive the configuration value or all configuration JSON - // - // len - [in] bytes of 'buf', [out] - content bytes in 'buf', or minimum size needed - // - // cfg_name - given configuration name, if set, put current value of the configuration in 'buf', - // or put all configurations JSON text in 'buf' if was nullptr. refer to SANE-config - // - // Return: 0 - on success - // EINVAL - if paramter 'len' was nullptr - // ENOMEM - if size of 'buf' was too small, the minimum size needed is stored in 'len' - // ENOENT - the configuration named 'cfg_name' has not found - virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr) = 0; - - // Function: set value of configuration named 'cfg_name' - // - // Parameters: cfg_name - the configuration name - // - // data - the value address, nullptr is for restore to default value - // (bool*), (int*), (double*), (char*) - // - // len - bytes in 'data' - // - // Return: 0 - on success - // EINVAL - parameter was invalid. 'cfg_name' was nullptr - // ENOENT - configuration 'cfg_name' was not found - // EUCLEAN - content in 'data' was not exact, the exact value is stored in 'data', and bytes in 'len' - virtual int32_t set_config(const char* cfg_name, void* data, size_t* len) = 0; -}; - diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_util.cpp b/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_util.cpp deleted file mode 100644 index acbbcfc..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_util.cpp +++ /dev/null @@ -1,472 +0,0 @@ -#include "ipc_util.h" - -#if !defined(WIN32) && !defined(_WIN64) -#include -#include -#include -#include -#include -#endif - -#include - -#include "log_util.h" -#include "sys_util.h" - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// linux_event -unsigned long linux_event::to_abs_time_us = 0; - -linux_event::linux_event(const char* desc) : waiting_(false), sem_(nullptr), desc_(desc ? desc : ""), first_(true), multi_proc_(false) -{ - log_cls::log(LOG_LEVEL_ALL, "+linux_event(%p) unamed for '%s' constructing ...\n", this, desc_.c_str()); - -#if defined(WIN32) || defined(_WIN64) - err_ = 0; - local_sem_ = CreateEventA(NULL, TRUE, FALSE, NULL); -#else - err_ = sem_init(&local_sem_, 0, 0); -#endif - - if (err_ == -1) - { - err_ = errno; - log_cls::log(LOG_LEVEL_FATAL, " %p: sem_init = %s\n", this, strerror(err_)); - } - else - { - sem_ = &local_sem_; - } -} -linux_event::linux_event(const char* name, const char* desc) : waiting_(false), sem_(nullptr), desc_(desc ? desc : ""), first_(true), multi_proc_(true) -{ - log_cls::log(LOG_LEVEL_ALL, "+linux_event(%p) of named '%s' for '%s' constructing ...\n", this, name, desc_.c_str()); -#if defined(WIN32) || defined(_WIN64) - local_sem_ = CreateEventA(NULL, TRUE, FALSE, name); - sem_ = &local_sem_; - if(local_sem_ == NULL) -#else - sem_ = sem_open(name, O_CREAT | O_EXCL, 0777, 0); - if (sem_ == (sem_t*)SEM_FAILED) -#endif - { - sem_ = nullptr; - err_ = errno; - log_cls::log(LOG_LEVEL_FATAL, " %p: sem_open(O_CREAT | O_EXCL) = %s\n", this, strerror(err_)); - if(err_ = EEXIST) - { -#if defined(WIN32) || defined(_WIN64) - local_sem_ = OpenEventA(EVENT_ALL_ACCESS, FALSE, name); - if(local_sem_ == NULL) -#else - sem_ = sem_open(name, 0666); - if (sem_ == (sem_t*)SEM_FAILED) -#endif - { - err_ = errno; - sem_ = nullptr; - log_cls::log(LOG_LEVEL_FATAL, " %p: sem_open = %s\n", this, strerror(err_)); - } - else - { - err_ = 0; - first_ = false; - } - } - } - else - { - name_ = name; - log_cls::log(LOG_LEVEL_DEBUG, " %p: created named sem OK.\n", this); -#if !defined(WIN32) && !defined(_WIN64) - err_ = sem_init(sem_, 1, 0); // this is used to initialize the event count, whether named or unamed - if (err_ == -1) - { - err_ = errno; - log_cls::log(LOG_LEVEL_FATAL, " %p: sem_init = %s\n", this, strerror(err_)); - sem_close(sem_); - sem_ = nullptr; - sem_unlink(name); - } -#endif - } -} -linux_event::linux_event(sem_t* mem_sem, bool first, const char* desc) : waiting_(false), sem_(mem_sem), desc_(desc ? desc : ""), first_(first), multi_proc_(true) -{ - log_cls::log(LOG_LEVEL_ALL, "+linux_event(%p) at mem(%p) for '%s' constructing ...\n", this, mem_sem, desc_.c_str()); - - if(first) - { -#if defined(WIN32) || defined(_WIN64) - sem_ = mem_sem; -#else - err_ = sem_init(sem_, 1, 0); -#endif - if (err_ == -1) - { - err_ = errno; - log_cls::log(LOG_LEVEL_FATAL, " %p: sem_init = %s\n", this, strerror(err_)); - } - } -} -linux_event::~linux_event() -{ - if (sem_) - { - char ptr[40] = {0}; - std::string tips(""); - - sprintf(ptr, " ~%p: ", this); - tips = ptr; - if(sem_ == &local_sem_ || (first_ && name_.empty())) - { -#if defined(WIN32) || defined(_WIN64) - CloseHandle(local_sem_); - local_sem_ = NULL; -#else - err_ = log_cls::log_when_err(sem_destroy(sem_), (tips + "sem_destroy").c_str()); - } - else - { - err_ = log_cls::log_when_err(sem_close(sem_), (tips + "sem_close").c_str()); - - // else // why not else ? we should ensure delete the kernel object when unused. - if(!name_.empty()) // i am the named object owner ! - { - err_ = log_cls::log_when_err(sem_unlink(name_.c_str()), (tips + "sem_unlink").c_str(), LOG_LEVEL_FATAL); // This will cause previously opened objects to never receive events, even if you reopen it. - } -#endif - } - } - log_cls::log(LOG_LEVEL_ALL, "-linux_event(%p) destroyed.\n", this); -} - -int32_t linux_event::clear_named_event(const char* name) -{ - int32_t err = 0; - -#if !defined(WIN32) && !defined(_WIN64) - sem_t* sem = sem_open(name, O_CREAT | O_EXCL, 0777, 0); - - if(sem == (sem_t*)SEM_FAILED) - { - if(errno == EEXIST) - { - err = sem_unlink(name); - if(err == -1) - err = errno; - } - else - { - return 0; - } - } - else - { - sem_close(sem); - sem_unlink(name); - } -#endif - - return err; -} - void linux_event::reset_calc_abs_time(unsigned us) - { - if(us == -1) - { - TIMEV now = {0}, after = {0}; - struct timespec abst = {0}; - - linux_event::to_abs_time_us = 10; - if(chronograph::now(&now)) - { - abst.tv_sec = now.tv_sec; - abst.tv_nsec = USEC_2_NS(now.tv_usec); - abst.tv_nsec += MSEC_2_NS(1) + linux_event::to_abs_time_us; - - // overflow ... - abst.tv_sec += abst.tv_nsec / SEC_2_NS(1); - abst.tv_nsec %= SEC_2_NS(1); - if(chronograph::now(&after)) - { - if(after.tv_usec > now.tv_usec) - linux_event::to_abs_time_us = after.tv_usec - now.tv_usec; - else - linux_event::to_abs_time_us = SEC_2_US(1) + after.tv_usec - now.tv_usec; - } - } - } - else - { - linux_event::to_abs_time_us = us; - } - } -bool linux_event::abs_time_after(struct timespec* abstm, unsigned ms) -{ - TIMEV now = {0}; - - if(!chronograph::now(&now)) - { - log_cls::log(LOG_LEVEL_FATAL, "gettimeofday faied: %s\n!", strerror(errno)); - time(&now.tv_sec); - } - abstm->tv_sec = now.tv_sec; - abstm->tv_nsec = USEC_2_NS(now.tv_usec); - abstm->tv_nsec += MSEC_2_NS(ms) + USEC_2_NS(linux_event::to_abs_time_us); - - // overflow ... - abstm->tv_sec += abstm->tv_nsec / SEC_2_NS(1); - abstm->tv_nsec %= SEC_2_NS(1); - - return true; -} - -bool linux_event::is_ready(void) -{ - return sem_ != nullptr; -} -bool linux_event::is_named_first(void) -{ - return !name_.empty(); -} -bool linux_event::wait_try(void) -{ -#if defined(WIN32) || defined(_WIN64) - return WaitForSingleObject(*sem_, 0) == WAIT_OBJECT_0; -#else - return sem_trywait(sem_) == 0; -#endif -} -bool linux_event::wait(unsigned timeout) -{ - bool waited = true; - - //log_cls::log(LOG_LEVEL_ALL, "linux_event(%p): waiting(%u) ...\n", this, timeout); - waiting_ = true; -#if defined(WIN32) || defined(_WIN64) - waited = WaitForSingleObject(*sem_, timeout) == WAIT_OBJECT_0; -#else - if (timeout == WAIT_INFINITE) - { - sem_wait(sem_); - } - else - { - struct timespec to = {0}; - - linux_event::abs_time_after(&to, timeout); - waited = sem_timedwait(sem_, &to) == 0; - } -#endif - waiting_ = false; - //log_cls::log(LOG_LEVEL_ALL, "linux_event(%p): waited(%u) = %d\n", this, timeout, waited); - - return waited; -} -void linux_event::trigger(void) -{ -#if defined(WIN32) || defined(_WIN64) - err_ = 0; - SetEvent(*sem_); -#else - err_ = sem_post(sem_); -#endif - - if(err_) - err_ = errno; - - //log_cls::log(LOG_LEVEL_ALL, "linux_event(%p): trigger = %s\n", this, err_ == 0 ? "OK" : strerror(errno)); -} -void linux_event::reset(void) -{ -#if defined(WIN32) || defined(_WIN64) - err_ = 0; - ResetEvent(*sem_); -#else - err_ = sem_init(sem_, multi_proc_, 0); -#endif - - if(err_) - err_ = errno; - - //log_cls::log(LOG_LEVEL_ALL, "linux_event(%p): reset = %s\n", this, err_ == 0 ? "OK" : strerror(errno)); -} -bool linux_event::is_waiting(void) -{ - return waiting_; -} - - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// shared_mem -#if !defined(WIN32) && !defined(_WIN64) -uint64_t shared_mem::mem_total_ = 0; -uint64_t shared_mem::page_unit_ = 0; -uint64_t shared_mem::huge_page_unit_ = 0; - - -shared_mem::shared_mem() : name_(""), id_(0), size_(0), shm_buf_(shared_mem::invalid_map_addr()), first_(false), shm_id_(-1) -{ - if (shared_mem::page_unit_ == 0) - shared_mem::init_page_info(); - - log_cls::log(LOG_LEVEL_ALL, "+shared_mem(%p) constructed, page size = %ld\n", this, page_unit_); -} -shared_mem::~shared_mem() -{ - close(); - log_cls::log(LOG_LEVEL_ALL, "-shared_mem(%p) destroyed.\n", this); -} - -void shared_mem::init_page_info(void) -{ - shared_mem::page_unit_ = sys_util::get_page_size(); - - // Hugepagesize: 2048 kB - if(sys_util::get_inf_file_data("/proc/meminfo", 80, "MemTotal: %ld", &shared_mem::mem_total_)) - shared_mem::mem_total_ *= 1024; - if(sys_util::get_inf_file_data("/proc/meminfo", 80, "Hugepagesize: %ld", &shared_mem::huge_page_unit_)) - shared_mem::huge_page_unit_ *= 1024; - - log_cls::log(LOG_LEVEL_DEBUG, "TotalMemory: %s, system page size: %s, huge page size %s\n" - , sys_util::format_readable_bytes(shared_mem::mem_total_).c_str() - , sys_util::format_readable_bytes(shared_mem::page_unit_).c_str() - , sys_util::format_readable_bytes(shared_mem::huge_page_unit_).c_str()); -} -char* shared_mem::invalid_map_addr(void) -{ - return (char*)-1; -} - -int32_t shared_mem::open(int32_t id, size_t* bytes, const char* name) -{ - key_t key = (key_t)-1; // ftok(name, id); - int32_t ret = close(); - size_t size = bytes ? *bytes : 0; - std::string pe(""); - - if (ret) - return ret; - - if(!name || *name == 0) - { - pe = sys_util::get_module_path(); - name = pe.c_str(); - } - key = ftok(name, id); - if (key == (key_t)-1) - { - log_cls::log(LOG_LEVEL_FATAL, "shared_memory(%p): ftok('%s', %d) = %s\n", this, name, id, strerror(errno)); - - return errno; - } - log_cls::log(LOG_LEVEL_DEBUG, "shared memory key: %p\n", key); - - size = ALIGN_INT(size, shared_mem::page_unit_); - if (!bytes || *bytes != size) - { - log_cls::log(LOG_LEVEL_DEBUG, "add %ld upto multiple of page size: %ld\n", bytes ? *bytes : 0, size); - if (bytes) - *bytes = size; - } - - shm_id_ = shmget(key, size, IPC_EXCL | IPC_CREAT | 0600); - if (shm_id_ == -1) - { - ret = errno; - log_cls::log(LOG_LEVEL_WARNING, "%p: create shared memory('%s', %d) failed: %s\n", this, name, id, strerror(ret)); - if (ret == EEXIST) - { - shm_id_ = shmget(key, size, 0600); - if (shm_id_ == -1) - { - ret = errno; - log_cls::log(LOG_LEVEL_WARNING, "%p: open shared memory('%s', %d) failed: %s\n", this, name, id, strerror(ret)); - } - else - { - ret = 0; - first_ = false; - } - } - } - else // i created the shared memory ... - { - first_ = true; - } - - if (ret == 0) - { - shm_buf_ = (char*)shmat(shm_id_, nullptr, 0); - if (shm_buf_ == shared_mem::invalid_map_addr()) - { - ret = errno; - log_cls::log(LOG_LEVEL_WARNING, "%p: shmat failed: %s\n", this, strerror(ret)); - close(); - } - else - { - log_cls::log(LOG_LEVEL_DEBUG, "%p: %s shared memory('%s', %d) at %p(+%s) OK.\n", this, first_ ? "create" : "open", name, id, shm_buf_, sys_util::format_readable_bytes(size).c_str()); - name_ = name; - id_ = id; - size_ = size; - } - } - - return ret; -} -int32_t shared_mem::close(void) -{ - int32_t ret = 0; - - if (shm_buf_ != shared_mem::invalid_map_addr()) - { - ret = log_cls::log_when_err(shmdt(shm_buf_), "shmdt"); - if (ret) - return ret; - - shm_buf_ = shared_mem::invalid_map_addr(); - } - if (first_ && shm_id_ >= 0) - { - ret = log_cls::log_when_err(shmctl(shm_id_, IPC_RMID, nullptr), "shmctrl(IPC_RMID)"); - if (ret && ret != ENOENT) - { - // re-map buffer ... - shm_buf_ = (char*)shmat(shm_id_, nullptr, 0); - - return ret; - } - - shm_id_ = -1; - } - - name_ = ""; - id_ = 0; - first_ = false; - size_ = 0; - - return ret; -} - -char* shared_mem::get_mem(size_t* size) -{ - if (size) - *size = size_; - - return shm_buf_ == shared_mem::invalid_map_addr() ? nullptr : shm_buf_; -} -bool shared_mem::is_first(void) -{ - return first_; -} - -void shared_mem::clear_kernel_object(void) -{ - log_cls::log_when_err(shmctl(shm_id_, IPC_RMID, nullptr), "shmctrl(IPC_RMID)"); -} - -#endif \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_util.h b/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_util.h deleted file mode 100644 index 3949d58..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_util.h +++ /dev/null @@ -1,160 +0,0 @@ -#pragma once - -// IPC utility -// -// created on 2022-11-29 -// - - -#include "referer.h" -#if defined(WIN32) || defined(_WIN64) -#include -#define sem_t HANDLE -#define SEM_FAILED NULL -#else -#include -#endif -#include - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// object event -// -class linux_event : public refer -{ - int32_t err_; - sem_t local_sem_; - sem_t* sem_; - bool first_; - bool multi_proc_; - volatile bool waiting_; - std::string desc_; - std::string name_; - - static unsigned long to_abs_time_us; // used in sem_timedwait to calculate absolute time from elapse - -public: - linux_event(const char* desc); // to initialize a in-process object - linux_event(const char* name, const char* desc); // to initialize a multi-process object - linux_event(sem_t* mem_sem, bool first/*invoke sem_init when true*/, const char* desc); // to initialize an event at given memory (shared memory) - - static int32_t clear_named_event(const char* name); - static void reset_calc_abs_time(unsigned us = -1); // reset 'to_abs_time_us' value, -1 is for re-calc - static bool abs_time_after(struct timespec* abstm, unsigned ms); - -protected: - ~linux_event(); - -public: - bool is_ready(void); - bool is_named_first(void); // whether I created the named event - bool wait_try(void); - bool wait(unsigned timeout = WAIT_INFINITE/*ms*/); // WAIT_INFINITE is waiting unfinite, true when watied and false for wait timeout - void trigger(void); - void reset(void); // re-initialize. DANGEROUS !!! all wait operation before will not receive any event after this !!! - bool is_waiting(void); -}; - - -template -class safe_fifo -{ - MUTEX lock_; - std::deque que_; - linux_event* wait_; - -public: - safe_fifo() : wait_(new linux_event("fifo")) - {} - ~safe_fifo() - { - wait_->release(); - } - -public: - void save(const T& t, bool notify = false) - { - LOCKER lock(lock_); - - que_.push_back(std::move(t)); - if (notify) - wait_->trigger(); - } - bool take(T& t, bool wait = false) - { - if (wait && size() == 0) - { - wait_->wait(); - wait_->reset(); - } - - { - LOCKER lock(lock_); - - if (que_.size()) - { - t = std::move(que_.front()); - que_.pop_front(); - - return true; - } - else - { - return false; - } - } - } - size_t size(void) - { - LOCKER lock(lock_); - - return que_.size(); - } - void clear(void) - { - LOCKER lock(lock_); - - que_.clear(); - } - void quit(void) - { - wait_->trigger(); - } -}; - -#if !defined(WIN32) && !defined(_WIN64) - -class shared_mem : public refer -{ - std::string name_; - int32_t id_; - int32_t shm_id_; - char* shm_buf_; - size_t size_; - bool first_; - -public: - shared_mem(); - - static void init_page_info(void); - static char* invalid_map_addr(void); - - static uint64_t mem_total_; - static uint64_t page_unit_; - static uint64_t huge_page_unit_; - -protected: - ~shared_mem(); - -public: - int32_t open(int32_t id, size_t* bytes, const char* name = nullptr); - int32_t close(void); - - char* get_mem(size_t* size = nullptr); - bool is_first(void); - - void clear_kernel_object(void); -}; - -#endif diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_wrapper.cpp b/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_wrapper.cpp deleted file mode 100644 index 5c9fdac..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_wrapper.cpp +++ /dev/null @@ -1,373 +0,0 @@ -#include "ipc_wrapper.h" - -#include -#include - -#include "log_util.h" -#include "ipc_util.h" -#include "sys_util.h" - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ipc_wrapper_shm -class ipc_wrapper_shm : public ipc_wrapper -{ - enum data_ind - { - DATA_INTER_CMD = 0, - }; - enum internal_cmd - { - INTER_CMD_NONE = 0, - INTER_CMD_EXIT, - }; - typedef struct _shm_pack - { - size_t space; // buffer length - size_t bytes; // data length - char data[4]; - }SHMPACK, *LPSHMPACK; - typedef struct _sync_shm // 1-lock(write_lock) --> 2-write content --> 3-notify read --> 4-wait(wait_sent) --> 5-return step 2 if data has not sent finished, or else to 6 --> 6-release(write_lock) --> 7-over - { - sem_t wait_arrive; // read event - sem_t wait_sent; // peer has read, i can re-write now - sem_t notify_read; // notify peer to read - sem_t notify_write; // notify peer to write - char data[8]; // internal data - }SYNCSHM, *LPSYNCSHM; - volatile bool run_; - MUTEX write_lock_; - int32_t id_; - shared_mem* shm_; - LPSYNCSHM sync_shm_; - linux_event* wait_arrive_; - linux_event* wait_sent_; - linux_event* notify_write_; - linux_event* notify_read_; - THREAD_PTR thread_; - LPSHMPACK buf_in_; - LPSHMPACK buf_out_; - bool buf_out_used_; - volatile bool cancel_write_; - - void create(const char* file, int32_t id, size_t bytes, unsigned sent_percent) - { - int32_t err = 0; - - shm_ = new shared_mem(); - err = shm_->open(id, &bytes, file); - if (err) - { - log_cls::log(LOG_LEVEL_FATAL, "ipc_wrapper_shm(%p) open shared memory(%s, %d, %s) failed: %s\n" - , this, file, id, sys_util::format_readable_bytes(bytes).c_str(), strerror(err)); - shm_->release(); - shm_ = nullptr; - - return; - } - - SHMPACK pack = { 0 }; - std::string desc("ipc_wrapper_shm-"); - char buf[80] = { 0 }, *ptr = shm_->get_mem(&pack.space); - int32_t pack_head = ALIGN_INT(sizeof(pack), 16), head = ALIGN_INT(sizeof(SYNCSHM), 16); - - sprintf(buf, "%d-", id); - desc += buf; - - sync_shm_ = (LPSYNCSHM)ptr; - ptr += head; - pack.space -= head + pack_head * 2; - head = ALIGN_INT(pack.space * sent_percent / 100, 16); - if (shm_->is_first()) - { - SYNCSHM ss; - - memcpy(sync_shm_, &ss, sizeof(ss)); - buf_in_ = (LPSHMPACK)ptr; - buf_in_->space = pack.space - head; - ptr += buf_in_->space + pack_head; - buf_out_ = (LPSHMPACK)ptr; - buf_out_->space = head; - //* - wait_arrive_ = new linux_event(&sync_shm_->wait_arrive, true, (desc + "wait_arrive").c_str()); - wait_sent_ = new linux_event(&sync_shm_->wait_sent, true, (desc + "wait_sent").c_str()); - notify_read_ = new linux_event(&sync_shm_->notify_read, true, (desc + "notify_read").c_str()); - notify_write_ = new linux_event(&sync_shm_->notify_write, true, (desc + "notify_write").c_str()); - /*/ - wait_arrive_ = new linux_event((desc + "wait_arrive").c_str(), ""); - wait_sent_ = new linux_event((desc + "wait_sent").c_str(), ""); - notify_write_ = new linux_event((desc + "notify_write").c_str(), ""); - notify_read_ = new linux_event((desc + "notify_read").c_str(), ""); - ///*//////////// - memset(sync_shm_->data, 0, sizeof(sync_shm_->data)); - } - else - { - //* - wait_sent_ = new linux_event(&sync_shm_->notify_write, false, (desc + "wait_sent").c_str()); - wait_arrive_ = new linux_event(&sync_shm_->notify_read, false, (desc + "wait_arrive").c_str()); - notify_write_ = new linux_event(&sync_shm_->wait_sent, false, (desc + "notify_write").c_str()); - notify_read_ = new linux_event(&sync_shm_->wait_arrive, false, (desc + "notify_read").c_str()); - /*/ - wait_arrive_ = new linux_event((desc + "notify_read").c_str(), ""); - wait_sent_ = new linux_event((desc + "notify_write").c_str(), ""); - notify_read_ = new linux_event((desc + "wait_arrive").c_str(), ""); - notify_write_ = new linux_event((desc + "wait_sent").c_str(), ""); - ///*//////////// - buf_out_ = (LPSHMPACK)ptr; - buf_in_ = (LPSHMPACK)(ptr + pack_head + buf_out_->space); - } - - thread_.reset(new std::thread(&ipc_wrapper_shm::read_thread, this)); - // handler_->on_event(event_handler::EVENT_WRITE, buf_out_->data, buf_size_); - } - void read_thread(void) - { - event_handler* handler = handler_; - - handler->add_ref(); - while (run_) - { - wait_arrive_->wait(); - if (!run_) - break; - if (!shm_->is_first() && sync_shm_->data[DATA_INTER_CMD] == INTER_CMD_EXIT) - break; - - handler->on_event(SCANNER_EVENT_IPC_DATA_RECEIVED, buf_in_->data, buf_in_->bytes); - notify_write_->trigger(); - } - handler->release(); - } - -public: - ipc_wrapper_shm(const char* file, int32_t id - , size_t bytes - , event_handler* handler - , unsigned sent_percent = 50) - : ipc_wrapper(handler), run_(true), shm_(nullptr), sync_shm_(nullptr) - , wait_arrive_(nullptr), wait_sent_(nullptr), notify_write_(nullptr), notify_read_(nullptr) - , buf_in_(nullptr), buf_out_(nullptr), id_(id), buf_out_used_(false), cancel_write_(false) - { - create(file, id, bytes, sent_percent); - } - -protected: - ~ipc_wrapper_shm() - {} - -public: - virtual int32_t write(const char* pack, size_t * bytes, bool kbuf, unsigned timeout = WAIT_INFINITE) override - { - if (!shm_) - return ENOTCONN; - - // invoke in read-thread is not allowed - if(std::this_thread::get_id() == thread_->get_id()) - return EDEADLOCK; - - LOCKER lock(write_lock_); - size_t rest = *bytes; - int32_t ret = 0; - - cancel_write_ = false; - if (kbuf) - { - buf_out_->bytes = rest; - notify_read_->trigger(); - if (wait_sent_->wait(timeout)) - rest = 0; - else - ret = ETIME; - } - else - { - chronograph timer; - while (rest) - { - buf_out_->bytes = rest > buf_out_->space ? buf_out_->space : rest; - memcpy(buf_out_->data, pack, buf_out_->bytes); - notify_read_->trigger(); - - pack += buf_out_->space; - if (!wait_sent_->wait(timeout)) - break; - if (cancel_write_) - break; - - if (rest <= buf_out_->space) - { - rest = 0; - break; - } - rest -= buf_out_->space; - - if (timeout) - { - uint64_t t = timer.elapse_ms(); - if (t >= timeout) - break; - - timeout -= t; - timer.reset(); - } - } - if (cancel_write_) - ret = ECANCELED; - else if (rest) - ret = ETIME; - } - *bytes -= rest; - - return ret; - } - virtual bool cancel_write(void) override - { - cancel_write_ = true; - if (wait_sent_->is_waiting()) - { - wait_sent_->trigger(); - wait_sent_->reset(); // sure ? - } - - return true; - } - virtual bool is_ok(void) override - { - return shm_ != nullptr; - } - virtual bool is_first(void) override - { - return shm_ && shm_->is_first(); - } - - virtual void* get_kbuf(size_t* bytes) override - { - if (!bytes) - return nullptr; - - if (buf_out_used_) - { - *bytes = 0; - - return nullptr; - } - - buf_out_used_ = true; - *bytes = buf_out_->space; - - return buf_out_->data; - } - virtual void release_kbuf(void* buf) override - { - buf_out_used_ = false; - } - virtual void clear_kernel_objects(void) override - { - std::string desc("ipc_wrapper_shm-"); - char id[20] = { 0 }; - - sprintf(id, "%d-", id_); - desc += id; - linux_event::clear_named_event((desc + "wait_arrive").c_str()); - linux_event::clear_named_event((desc + "wait_sent").c_str()); - linux_event::clear_named_event((desc + "notify_write").c_str()); - linux_event::clear_named_event((desc + "notify_read").c_str()); - - shm_->clear_kernel_object(); - } - virtual int32_t stop(void) override - { - run_ = false; - if (shm_) - { - wait_arrive_->trigger(); - if (thread_.get() && thread_->joinable()) - thread_->join(); - thread_.reset(); - - if (is_first()) - { - sync_shm_->data[DATA_INTER_CMD] = INTER_CMD_EXIT; - notify_read_->trigger(); - wait_sent_->wait(100); - } - notify_read_->release(); - notify_read_ = nullptr; - notify_write_->release(); - notify_write_ = nullptr; - wait_arrive_->release(); - wait_arrive_ = nullptr; - wait_sent_->release(); - wait_sent_ = nullptr; - sync_shm_ = nullptr; - buf_in_ = buf_out_ = nullptr; - - shm_->close(); - shm_->release(); - } - shm_ = nullptr; - - return ipc_wrapper::stop(); - } - -}; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ipc_wrapper -ipc_wrapper::ipc_wrapper(event_handler* handler) : handler_(handler) -{ - if (handler_) - handler_->add_ref(); -} -ipc_wrapper::~ipc_wrapper() -{} - -void* ipc_wrapper::get_kbuf(size_t* bytes) -{ - if (bytes) - *bytes = 0; - - return nullptr; -} -void ipc_wrapper::release_kbuf(void* buf) -{} -void ipc_wrapper::clear_kernel_objects(void) -{} -bool ipc_wrapper::cancel_write(void) -{ - return false; -} -int32_t ipc_wrapper::stop(void) -{ - if (handler_) - handler_->release(); - handler_ = nullptr; - - return 0; -} - -ipc_wrapper* ipc_wrapper::create_ipc(event_handler* handler, ipc_type type, const char* param) -{ - if (type == IPC_SHARED_MEM) - { - // path-file:id:size[:write-ratio-> percent of size of sent buffer, default is 50, only valid in owner] - std::string file(param); - size_t pos = file.rfind(':'); - std::vector params; - - while(pos != std::string::npos && params.size() < 3) - { - params.push_back(std::stold(file.substr(pos + 1))); - file.erase(pos); - pos = file.rfind(':'); - } - if(params.size() >= 2) - { - params.insert(params.begin(), 50); - pos = params.size(); - - return dynamic_cast(new ipc_wrapper_shm(file.c_str(), params[pos - 1], params[pos - 2], handler, params[pos - 3])); - } - } - return nullptr; -} diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_wrapper.h b/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_wrapper.h deleted file mode 100644 index 1263de0..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/ipc_wrapper.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -// IPC utility -// -// created on 2022-12-02 -// - - -#include "event_monitor.h" - - -class ipc_wrapper : public parent_holder -{ -protected: - event_handler* handler_; - -public: - ipc_wrapper(event_handler* handler); - - enum ipc_type - { - IPC_FILE = 0, // param: path file - IPC_PIPE, // param: pipe name - IPC_NET, // param: dot-ip:port - IPC_SHARED_MEM, // param: path-file:id:size[:write-ratio-> percent of size of sent buffer, default is 50, only valid in owner] - IPC_USB, // param: vid:pid - IPC_COM, // param: COM1 - }; - static ipc_wrapper* create_ipc(event_handler* handler, ipc_type type, const char* param); - -protected: - virtual ~ipc_wrapper(); - -public: - // Function: write content to peer - // - // Parameters: pack - content pack - // - // bytes - [in] bytes of data in 'pack', [out] - bytes of data has sent - // - // kbuf - whether memory 'pack' is from IPC, i.e. return from method get_kbuf() - // - // timeout - time out, in milliseconds - // - // Return: 0 - success - // ENOTCONN - the commuction is not connected, equal to !is_ok() - // EDEADLOCK - calling from current thread is disallowed - // ETIME - time out - // ECANCELED - user cancelled the operation - virtual int32_t write(const char* pack, size_t *bytes, bool kbuf, unsigned timeout = WAIT_INFINITE) = 0; // DON'T call in event_handler::on_event routine, it will be DEAD-LOCK !!! - virtual bool is_ok(void) = 0; // whether the commuction is ready - virtual bool is_first(void) = 0; // whether the communication established by me - - // Function: obtain IPC internal buffer to reduce ONE memory copy for sent data - // - // Parameter: bytes - [in] desired size; [out] - real size - // - // Return: memory pointer if success, or nullptr. call release_kbuf(ptr) if no longer used - virtual void* get_kbuf(size_t* bytes); - virtual void release_kbuf(void* buf); // release the internal buffer returned by get_kbuf - virtual void clear_kernel_objects(void); // clear all kernel objects the IPC used, used to clear exception - virtual bool cancel_write(void); // cancel current write operation - virtual int32_t stop(void) override; // close the connection -}; diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/json/cJSON.h b/device/gxx-linux/testusb/usb-rk3399/src/common/json/cJSON.h deleted file mode 100644 index 913bc1e..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/json/cJSON.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - Copyright (c) 2009 Dave Gamble - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef cJSON__h -#define cJSON__h -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* cJSON Types: */ -#define cJSON_False 0 -#define cJSON_True 1 -#define cJSON_NULL 2 -#define cJSON_Number 3 -#define cJSON_String 4 -#define cJSON_Array 5 -#define cJSON_Object 6 - -#define cJSON_IsReference 256 -#define cJSON_StringIsConst 512 - - -typedef void *(*malloc_fnxx)(size_t sz); -typedef void (*free_fnxx)(void *ptr); - -/* The cJSON structure: */ -typedef struct cJSON { - struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ - struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ - - int type; /* The type of the item, as above. */ - - char *valuestring; /* The item's string, if type==cJSON_String */ - int valueint; /* The item's number, if type==cJSON_Number */ - double valuedouble; /* The item's number, if type==cJSON_Number */ - - char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ -} cJSON; - -typedef struct cJSON_Hooks { - malloc_fnxx malloc_fn; - free_fnxx free_fn; -} cJSON_Hooks; - -/* Supply malloc, realloc and free functions to cJSON */ -extern void cJSON_InitHooks(cJSON_Hooks* hooks); - - -/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ -extern cJSON *cJSON_Parse(const char *value); -/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ -extern char *cJSON_Print(cJSON *item); -/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ -extern char *cJSON_PrintUnformatted(cJSON *item); -/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ -extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt); -/* Delete a cJSON entity and all subentities. */ -extern void cJSON_Delete(cJSON *c); - -/* Returns the number of items in an array (or object). */ -extern int cJSON_GetArraySize(cJSON *array); -/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ -extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); -/* Get item "string" from object. Case insensitive. */ -extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); - -/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ -extern const char *cJSON_GetErrorPtr(void); - -/* These calls create a cJSON item of the appropriate type. */ -extern cJSON *cJSON_CreateNull(void); -extern cJSON *cJSON_CreateTrue(void); -extern cJSON *cJSON_CreateFalse(void); -extern cJSON *cJSON_CreateBool(int b); -extern cJSON *cJSON_CreateNumber(double num); -extern cJSON *cJSON_CreateString(const char *string); -extern cJSON *cJSON_CreateArray(void); -extern cJSON *cJSON_CreateObject(void); - -/* These utilities create an Array of count items. */ -extern cJSON *cJSON_CreateIntArray(const int *numbers,int count); -extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); -extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count); -extern cJSON *cJSON_CreateStringArray(const char **strings,int count); - -/* Append item to the specified array/object. */ -extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); -extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); -extern void cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object */ -/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ -extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); -extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); - -/* Remove/Detatch items from Arrays/Objects. */ -extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); -extern void cJSON_DeleteItemFromArray(cJSON *array,int which); -extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); -extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); - -/* Update array items. */ -extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem); /* Shifts pre-existing items to the right. */ -extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); -extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); - -/* Duplicate a cJSON item */ -extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); -/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will -need to be released. With recurse!=0, it will duplicate any children connected to the item. -The item->next and ->prev pointers are always zero on return from Duplicate. */ - -/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ -extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); - -extern void cJSON_Minify(char *json); - -// convert e681a2 to \u6062, call 'free' to free the returned value -extern char* cJSON_utf8_2_unic(const char* utf8); - -/* Macros for creating things quickly. */ -#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) -#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) -#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) -#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) -#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) -#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) - -/* When assigning an integer value, it needs to be propagated to valuedouble too. */ -#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) -#define cJSON_SetNumberValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/json/json.cpp b/device/gxx-linux/testusb/usb-rk3399/src/common/json/json.cpp deleted file mode 100644 index e8ae93f..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/json/json.cpp +++ /dev/null @@ -1,786 +0,0 @@ - -#include "json.h" -#include "cJSON.h" -#include -#include - -namespace special_char_trans -{ - struct - { - const char* writedown_text; - char readable_char; - }transferred_chars[] = { { "\\\"", '\"' } - , { "\\'", '\'' } - , { "\\a", '\a' } - , { "\\b", '\b' } - , { "\\f", '\f' } - , { "\\n", '\n' } - , { "\\r", '\r' } - , { "\\t", '\t' } - , { "\\v", '\v' } - // , { "\\?", '\?' } - , { "\\\\", '\\' } - , { "\\/", '/' } - // , { "\\0", '\0' } - }; - - void to_writedown(std::string& str) - { - std::string trans(str); - const char* ptr = trans.c_str(); - - str.clear(); - while (*ptr) - { - bool rep = false; - if (*ptr == '\\') - { - if (ptr[1] == '\\') - { - str += "\\\\"; - ptr++; - rep = true; - } - else if( ptr[1] == '/' || - ptr[1] == 'a' || - ptr[1] == 'b' || - ptr[1] == 'f' || - ptr[1] == 'n' || - ptr[1] == 'r' || - ptr[1] == 't' || - ptr[1] == 'u' || - ptr[1] == 'v') - { - str += "\\"; - ptr++; - } - else - { - str += "\\\\"; - rep = true; - } - } - else - { - for (size_t i = 0; i < sizeof(transferred_chars) / sizeof(transferred_chars[0]); ++i) - { - if (*ptr == transferred_chars[i].readable_char) - { - str += transferred_chars[i].writedown_text; - rep = true; - break; - } - } - } - if (!rep) - str.append(1, *ptr); - ptr++; - } - } -} - - -json::json(char* json_txt) : type_(VAL_TYPE_OBJECT), key_(""), strval_(""), cur_child_(-1) -{ - simple_val_.dval = .0f; - if(json_txt) - attach_text(json_txt); -} -json::json(const char* key, bool val) : type_(VAL_TYPE_BOOL), key_(key ? key : ""), strval_(""), cur_child_(-1) -{ - simple_val_.bval = val; -} -json::json(const char* key, int val) : type_(VAL_TYPE_INT), key_(key ? key : ""), strval_(""), cur_child_(-1) -{ - simple_val_.nval = val; -} -json::json(const char* key, double val) : type_(VAL_TYPE_FLOAT), key_(key ? key : ""), strval_(""), cur_child_(-1) -{ - simple_val_.dval = val; -} -json::json(const char* key, const char* val) : type_(VAL_TYPE_STRING), key_(key ? key : ""), strval_(val ? val : ""), cur_child_(-1) -{} -json::~json() -{ - clear(); -} - -std::string json::object_key(json* jsn) -{ - return "\"" + jsn->key() + "\":"; -} -std::string json::array_key(json* jsn) -{ - return ""; -} - -void json::from_cjson(cJSON* cj) -{ - key_ = cj && cj->string ? cj->string : ""; - while (cj) - { - json* child = nullptr; - if (cj->type == cJSON_True) - { - child = new json(cj->string, true); - } - else if(cj->type == cJSON_False) - { - child = new json(cj->string, false); - } - else if (cj->type == cJSON_Number) - { - if (cj->valuedouble - (int)cj->valuedouble < .00001) - { - child = new json(cj->string, cj->valueint); - } - else - { - child = new json(cj->string, cj->valuedouble); - } - } - else if (cj->type == cJSON_String) - { - child = new json(cj->string, cj->valuestring); - } - else if (cj->type == cJSON_Object || cj->type == cJSON_Array) - { - child = new json(); - child->from_cjson(cj->child); - child->key_ = cj->string ? cj->string : ""; - } - arr_val_.push_back(child); - cj = cj->next; - } - - if (arr_val_.size() == 1 && arr_val_[0]->arr_val_.size() == 0) - { - json* child = arr_val_[0]; - - if (!child->key_.empty()) // array - { - arr_val_.clear(); - type_ = child->type_; - key_ = child->key_; - simple_val_.dval = child->simple_val_.dval; - strval_ = child->strval_; - for (auto& v : child->arr_val_) - arr_val_.push_back(v); - child->arr_val_.clear(); - child->release(); - } - } - - if (arr_val_.size()) - { - type_ = arr_val_[0]->key().empty() ? VAL_TYPE_ARRAY : VAL_TYPE_OBJECT; - } -} -json* json::find_child(const char* key, bool remove) -{ - json* ret = nullptr; - - if (type_ == VAL_TYPE_OBJECT) - { - for (size_t i = 0; i < arr_val_.size(); ++i) - { - if (arr_val_[i]->key() == key) - { - ret = arr_val_[i]; - if (remove) - arr_val_.erase(arr_val_.begin() + i); - else - ret->add_ref(); - - break; - } - } - } - - return ret; -} - -bool json::attach_text(char* json_txt) -{ - clear(); - - cJSON* jsn = cJSON_Parse(json_txt); - if (jsn) - { - char *text = cJSON_Print(jsn); - if (text) - free(text); - - from_cjson(jsn->child); - cJSON_Delete(jsn); - - return true; - } - - return false; -} -void json::clear(bool as_array) -{ - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - for (auto& v : arr_val_) - v->release(); - } - type_ = as_array ? VAL_TYPE_ARRAY : VAL_TYPE_OBJECT; - simple_val_.dval = .0f; - key_ = ""; - strval_ = ""; - arr_val_.clear(); - cur_child_ = -1; -} -std::string json::to_string(void) -{ - if (type_ == VAL_TYPE_NULL) - return ""; - if (type_ == VAL_TYPE_BOOL) - return (simple_val_.bval ? "true" : "false"); - if (type_ == VAL_TYPE_INT) - return std::to_string(simple_val_.nval); - if (type_ == VAL_TYPE_FLOAT) - return std::to_string(simple_val_.dval); - if (type_ == VAL_TYPE_STRING) - { - char* u = cJSON_utf8_2_unic(strval_.c_str()); - std::string r(u); - - free(u); - special_char_trans::to_writedown(r); - - return "\"" + r + "\""; - } - - std::string(*k)(json*) = type_ == VAL_TYPE_OBJECT ? json::object_key : json::array_key; - std::string str(type_ == VAL_TYPE_OBJECT ? "{" : "["); - - if (arr_val_.size()) - { - str += k(arr_val_[0]) + arr_val_[0]->to_string(); - for(size_t i = 1; i < arr_val_.size(); ++i) - str += "," + k(arr_val_[i]) + arr_val_[i]->to_string(); - } - str += type_ == VAL_TYPE_OBJECT ? "}" : "]"; - - return str; -} - -std::string& json::key(void) -{ - return key_; -} -bool json::is_array(void) -{ - return type_ == VAL_TYPE_ARRAY; -} -bool json::is_leaf_node(void) -{ - return type_ == VAL_TYPE_BOOL || - type_ == VAL_TYPE_INT || - type_ == VAL_TYPE_FLOAT || - type_ == VAL_TYPE_STRING; -} - -bool json::get_value(const char* key, bool& val) -{ - bool ret = false; - json* child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_BOOL) - { - val = child->simple_val_.bval; - ret = true; - } - child->release(); - } - else if (type_ == VAL_TYPE_BOOL && key_ == key) - { - val = simple_val_.bval; - ret = true; - } - - return ret; -} -bool json::get_value(const char* key, int& val) -{ - bool ret = false; - json* child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_INT) - { - val = child->simple_val_.nval; - ret = true; - } - child->release(); - } - else if (type_ == VAL_TYPE_INT && key_ == key) - { - val = simple_val_.nval; - ret = true; - } - - return ret; -} -bool json::get_value(const char* key, double& val) -{ - bool ret = false; - json* child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_FLOAT) - { - val = child->simple_val_.dval; - ret = true; - } - child->release(); - } - else if (type_ == VAL_TYPE_FLOAT && key_ == key) - { - val = simple_val_.dval; - ret = true; - } - - return ret; -} -bool json::get_value(const char* key, std::string& val) -{ - bool ret = false; - json* child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_STRING) - { - val = child->strval_; - ret = true; - } - child->release(); - } - else if (type_ == VAL_TYPE_STRING && key_ == key) - { - val = strval_; - ret = true; - } - - return ret; -} -bool json::get_value(const char* key, json*& val) -{ - bool ret = false; - json *child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_OBJECT) - { - val = child; - ret = true; - } - else - { - child->release(); - } - } - - return ret; -} - -size_t json::children(void) -{ - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - return arr_val_.size(); - else - return -1; -} -json* json::child(size_t ind) -{ - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - if (ind >= 0 && ind < arr_val_.size()) - { - arr_val_[ind]->add_ref(); - - return arr_val_[ind]; - } - } - - return nullptr; -} -json* json::first_child(void) -{ - if (type_ == VAL_TYPE_OBJECT || type_ == VAL_TYPE_ARRAY) - { - cur_child_ = 0; - if (arr_val_.size()) - { - arr_val_[0]->add_ref(); - - return arr_val_[0]; - } - } - - return nullptr; -} -json* json::next_child(void) -{ - if (type_ == VAL_TYPE_OBJECT || type_ == VAL_TYPE_ARRAY) - { - if (++cur_child_ < arr_val_.size()) - { - arr_val_[cur_child_]->add_ref(); - - return arr_val_[cur_child_]; - } - } - - return nullptr; -} - -bool json::set_value(const char* key, bool val) -{ - if (type_ != VAL_TYPE_OBJECT) - return false; - - json* child = find_child(key); - - if (child) - { - child->clear(); - child->type_ = VAL_TYPE_BOOL; - child->key() = key ? key : ""; - child->simple_val_.bval = val; - child->release(); - } - else - { - child = new json(key, val); - arr_val_.push_back(child); - } - - return true; -} -bool json::set_value(const char* key, int val) -{ - if (type_ != VAL_TYPE_OBJECT) - return false; - - json* child = find_child(key); - - if (child) - { - child->clear(); - child->type_ = VAL_TYPE_INT; - child->key() = key ? key : ""; - child->simple_val_.nval = val; - child->release(); - } - else - { - child = new json(key, val); - arr_val_.push_back(child); - } - - return true; -} -bool json::set_value(const char* key, double val) -{ - if (type_ != VAL_TYPE_OBJECT) - return false; - - json* child = find_child(key); - - if (child) - { - child->clear(); - child->type_ = VAL_TYPE_FLOAT; - child->key() = key ? key : ""; - child->simple_val_.dval = val; - child->release(); - } - else - { - child = new json(key, val); - arr_val_.push_back(child); - } - - return true; -} -bool json::set_value(const char* key, const char* val) -{ - if (type_ != VAL_TYPE_OBJECT) - return false; - - json* child = find_child(key); - - if (child) - { - child->clear(); - child->type_ = VAL_TYPE_STRING; - child->key() = key ? key : ""; - child->strval_ = val ? val : ""; - child->release(); - } - else - { - child = new json(key, val); - arr_val_.push_back(child); - } - - return true; -} -bool json::set_value(const char* key, json* val) -{ - if (type_ != VAL_TYPE_OBJECT) - return false; - - for (size_t i = 0; i < arr_val_.size(); ++i) - { - if (arr_val_[i]->key() == key) - { - arr_val_[i]->release(); - arr_val_[i] = val; - val->add_ref(); - return true; - } - } - - arr_val_.push_back(val); - val->key() = key; - val->add_ref(); - - return true; -} - -json& json::operator+=(bool val) -{ - if (type_ == VAL_TYPE_ARRAY) - { - json* child = new json(nullptr, val); - arr_val_.push_back(child); - } - - return *this; -} -json& json::operator+=(int val) -{ - if (type_ == VAL_TYPE_ARRAY) - { - json* child = new json(nullptr, val); - arr_val_.push_back(child); - } - - return *this; -} -json& json::operator+=(double val) -{ - if (type_ == VAL_TYPE_ARRAY) - { - json* child = new json(nullptr, val); - arr_val_.push_back(child); - } - - return *this; -} -json& json::operator+=(const char* val) -{ - if (type_ == VAL_TYPE_ARRAY) - { - json* child = new json(nullptr, val); - arr_val_.push_back(child); - } - - return *this; -} -json& json::operator+=(json* val) -{ - if (type_ == VAL_TYPE_ARRAY) - { - val->add_ref(); - arr_val_.push_back(val); - } - - return *this; -} - -json& json::operator-=(int ind) -{ - remove(ind); - - return *this; -} -bool json::remove(const char* key) -{ - json* child = find_child(key, true); - - if (child) - { - child->release(); - return true; - } - else - { - return false; - } -} -bool json::remove(json* child) -{ - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - for (size_t i = 0; i < arr_val_.size(); ++i) - { - if (arr_val_[i] == child) - { - arr_val_[i]->release(); - arr_val_.erase(arr_val_.begin() + i); - - return true; - } - } - } - - return false; -} -bool json::remove(int ind) -{ - bool ret = false; - - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - if (ind >= 0 && ind < arr_val_.size()) - { - arr_val_[ind]->release(); - arr_val_.erase(arr_val_.begin() + ind); - ret = true; - } - } - - return ret; -} - -int json::index(json* child) -{ - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - for (int i = 0; i < arr_val_.size(); ++i) - { - if (arr_val_[i] == child) - return i; - } - } - - return -1; -} -int json::index_move_to(json* child, int ind) -{ - int i = index(child); - - if (i == -1) - return -1; - - arr_val_.erase(arr_val_.begin() + i); - if (ind < 0) - ind = 0; - if (ind > arr_val_.size()) - ind = arr_val_.size(); - arr_val_.insert(arr_val_.begin() + ind, child); - - return ind; -} - -bool json::value(bool& val) -{ - bool ret = false; - - if (is_leaf_node() && type_ == VAL_TYPE_BOOL) - { - val = simple_val_.bval; - ret = true; - } - - return ret; -} -bool json::value(int& val) -{ - bool ret = false; - - if (is_leaf_node() && type_ == VAL_TYPE_INT) - { - val = simple_val_.nval; - ret = true; - } - - return ret; -} -bool json::value(double& val) -{ - bool ret = false; - - if (is_leaf_node() && type_ == VAL_TYPE_FLOAT) - { - val = simple_val_.dval; - ret = true; - } - - return ret; -} -bool json::value(std::string& val) -{ - bool ret = false; - - if (is_leaf_node() && type_ == VAL_TYPE_STRING) - { - val = strval_; - ret = true; - } - - return ret; -} -json& json::operator=(bool val) -{ - if (is_leaf_node()) - { - simple_val_.bval = val; - type_ = VAL_TYPE_BOOL; - } - - return *this; -} -json& json::operator=(int val) -{ - if (is_leaf_node()) - { - simple_val_.nval = val; - type_ = VAL_TYPE_INT; - } - - return *this; -} -json& json::operator=(double val) -{ - if (is_leaf_node()) - { - simple_val_.dval = val; - type_ = VAL_TYPE_FLOAT; - } - - return *this; -} -json& json::operator=(const char* val) -{ - if (is_leaf_node()) - { - strval_ = val ? val : ""; - type_ = VAL_TYPE_STRING; - } - - return *this; -} diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/json/json.h b/device/gxx-linux/testusb/usb-rk3399/src/common/json/json.h deleted file mode 100644 index 3adff81..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/json/json.h +++ /dev/null @@ -1,148 +0,0 @@ -#pragma once - -#ifdef TEST_JSON -#include -class refer -{ - volatile int32_t ref_; - std::mutex mutex_; - -protected: - refer() : ref_(1) - {} - virtual ~refer() - {} - - virtual void on_born(void) {} - virtual void on_dead(void) {} - -public: - virtual int32_t add_ref(void) - { - std::lock_guard l(mutex_); - - return ++ref_; - } - virtual int32_t release(void) - { - int32_t ref; - - { - std::lock_guard l(mutex_); - ref = --ref_; - } - - if (ref == 0) - { - delete this; - } - - return ref; - } -}; -#else -#include "../referer.h" -#endif -#include -#include - -struct cJSON; - -class json : public refer -{ - enum val_type - { - VAL_TYPE_NULL = 0, - VAL_TYPE_BOOL, - VAL_TYPE_INT, - VAL_TYPE_FLOAT, - VAL_TYPE_STRING, - VAL_TYPE_OBJECT, - VAL_TYPE_ARRAY, - }; - val_type type_; - std::string key_; - union - { - bool bval; - int nval; - double dval; - }simple_val_; - std::string strval_; - std::vector arr_val_; - size_t cur_child_; - - static std::string object_key(json* jsn); - static std::string array_key(json* jsn); - - void from_cjson(cJSON* cj); - json* find_child(const char* key, bool remove = false); - -public: - json(char* json_txt = 0); - -protected: - json(const char* key, bool val); - json(const char* key, int val); - json(const char* key, double val); - json(const char* key, const char* val); - ~json(); - -public: - // parse/un-parse ... - bool attach_text(char* json_txt); - void clear(bool as_array = false); - std::string to_string(void); - - // attributes ... - std::string& key(void); - bool is_array(void); - bool is_leaf_node(void); // whether this object is a leaf node contains final value - - // value access ... - bool get_value(const char* key, bool& val); - bool get_value(const char* key, int& val); - bool get_value(const char* key, double& val); - bool get_value(const char* key, std::string& val); - bool get_value(const char* key, json*& val); - - // enumeration ... - size_t children(void); // return children count if was object or array, or else -1 returned - json* child(size_t ind); - json* first_child(void); - json* next_child(void); - - // change the item matching 'key', otherwise add a new item - bool set_value(const char* key, bool val); - bool set_value(const char* key, int val); - bool set_value(const char* key, double val); - bool set_value(const char* key, const char* val); - bool set_value(const char* key, json* val); - - // operator+= only for array - json& operator+=(bool val); - json& operator+=(int val); - json& operator+=(double val); - json& operator+=(const char* val); - json& operator+=(json* val); - - // remove item - json& operator-=(int ind); - bool remove(const char* key); - bool remove(json* child); - bool remove(int ind); - - // position management - int index(json* child); - int index_move_to(json* child, int ind); - - // leaf node value ... - bool value(bool& val); - bool value(int& val); - bool value(double& val); - bool value(std::string& val); - json& operator=(bool val); - json& operator=(int val); - json& operator=(double val); - json& operator=(const char* val); -}; diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/log_util.cpp b/device/gxx-linux/testusb/usb-rk3399/src/common/log_util.cpp deleted file mode 100644 index a90f48f..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/log_util.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include "log_util.h" - -#include -#include -#include - -#if !defined(WIN32) && !defined(_WIN64) -#include -#include -#include -#include "sys_util.h" - -#else -#include -#include - - -namespace sys_util -{ - static std::string get_module_path(const char* name = NULL) - { - char path[MAX_PATH] = { 0 }; - - GetModuleFileNameA(NULL, path, _countof(path) - 1); - - return path; - } -} -#endif - -#include "referer.h" - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// class�� -log_cls* log_cls::inst_ = nullptr; - -log_cls::log_cls(const char* path_file, log_level level, int32_t max_size) : file_(path_file), max_size_(max_size), level_(level), dst_(nullptr) -{ - create_log_file(); -} -log_cls::~log_cls() -{ - if (dst_) - fclose(dst_); -} - -void log_cls::create_log_file(void) -{ - dst_ = fopen(file_.c_str(), "a+b"); - if (dst_) - { - fseek(dst_, 0, SEEK_END); - if (ftell(dst_) == 0) - { - unsigned char bom[] = { 0x0ef, 0x0bb, 0x0bf }; - fwrite(bom, sizeof(bom), 1, dst_); - } - else - fwrite("\n\n\n", 1, 3, dst_); - } - else - printf("# Failed to create log file(%s): %d(%s)\n", file_.c_str(), errno, strerror(errno)); -} - -void log_cls::log_internal(const char* txt) -{ - std::string now("[" + chronograph::now() + "] "); - - now += txt; - { - LOCKER locker(lock_); - if (dst_) - { - size_t wrote = fwrite(now.c_str(), 1, now.length(), dst_); - if(wrote != now.length()) - printf("# Write log failed: %d(%s)\n", errno, strerror(errno)); - - fflush(dst_); - if (ftell(dst_) >= max_size_) - { - fclose(dst_); - remove(file_.c_str()); - create_log_file(); - } - } - } -} - -void log_cls::initialize(const char* path_file, log_level level, int32_t max_size) -{ - if (log_cls::inst_) - delete log_cls::inst_; - - std::string path(""); - - if (!path_file || *path_file == 0) - { - size_t pos = 0; - std::string def_dir(std::string(getenv(USER_DIR)) + PATH_SEPARATOR + ".scanner"); // +PATH_SEPARATOR + "log"); - -#if defined(WIN32) || defined(_WIN64) - mkdir(def_dir.c_str()); -#endif - - def_dir += std::string(PATH_SEPARATOR) + "log"; - path = sys_util::get_module_path(); - pos = path.rfind(PATH_SEPARATOR[0]); - if (pos++ != std::string::npos) - path.erase(0, pos); - path.insert(0, def_dir + PATH_SEPARATOR); -#if defined(WIN32) || defined(_WIN64) - mkdir(def_dir.c_str()); -#else - sys_util::create_folder(def_dir.c_str()); -#endif - path += ".log"; - path_file = path.c_str(); - } - log_cls::inst_ = new log_cls(path_file, level, max_size); -} -int32_t log_cls::log_when_err(int32_t err, const char* oper_desc, log_level level) -{ - if(err == -1) - { - err = errno; - log_cls::log(level, "%s = %s\n", oper_desc, strerror(err)); - } - - return err; -} -log_level log_cls::get_log_level(void) -{ - if (log_cls::inst_) - return log_cls::inst_->level_; - else - return LOG_LEVEL_ALL; -} -std::string log_cls::get_log_file(void) -{ - if (log_cls::inst_) - return log_cls::inst_->file_; - else - return ""; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/log_util.h b/device/gxx-linux/testusb/usb-rk3399/src/common/log_util.h deleted file mode 100644 index 3778ba0..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/log_util.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -// log utility -// -// created on 2022-11-30 -// - - -#include "referer.h" -#include -#include - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// object event -// -enum log_level -{ - LOG_LEVEL_ALL = 0, - LOG_LEVEL_DEBUG, - LOG_LEVEL_WARNING, - LOG_LEVEL_FATAL, -}; - -class log_cls -{ - std::string file_; - int32_t max_size_; - log_level level_; - MUTEX lock_; - FILE *dst_; - - static log_cls* inst_; - - void create_log_file(void); - -protected: - log_cls(const char* path_file, log_level level, int32_t max_size); - ~log_cls(); - - void log_internal(const char* txt); - -public: - static void initialize(const char* path_file, log_level level = LOG_LEVEL_ALL, int32_t max_size = SIZE_MB(10)); - - template - static void log(log_level level, const char* fmt, Args ... args) - { - if (level >= log_cls::get_log_level() && log_cls::inst_) - { - size_t size = snprintf(nullptr, 0, fmt, args ...) + 1; - std::unique_ptr buf(new char[size]); - - snprintf(buf.get(), size, fmt, args ...); - - log_cls::inst_->log_internal(buf.get()); - } - } - static int32_t log_when_err(int32_t err, const char* oper_desc, log_level level = LOG_LEVEL_WARNING); // log as: oper_desc = strerror(errno)\n. return real error number errno - - static log_level get_log_level(void); - static std::string get_log_file(void); -}; diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/packet.h b/device/gxx-linux/testusb/usb-rk3399/src/common/packet.h deleted file mode 100644 index 4f14a56..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/packet.h +++ /dev/null @@ -1,315 +0,0 @@ -#pragma once - -// packet structures and command -// -// created on 2022-12-06 -// -#if !defined(WIN32) -#include -#endif -#include - -/////////////////////////////////////////////////////////////////////////////// -// definitions ... -#define CONFIG_NAME_MAX_LEN 32 // max bytes of configuration name -#define MAKE_WORD(b0, b1) (((b0) & 0xff) | (((b1) << 8) & 0x0ff00)) -#define ROGER(cmd) cmd##_ROGER -#define PAIR_COMMAND(cmd) \ - cmd, \ - cmd##_ROGER - -#define STRUCT_CONSTRUCTOR(st_name) \ - st_name() \ - { \ - memset(this, 0, sizeof(st_name));\ - } - -// protocol version, The first thing to do after connecting is to check whether the field is compatible !!! -#define PROTOCOL_VER MAKE_WORD(0, 1) - -// NOTE: All text transmitted by pack cmd is in UTF-8 format !!! - - -enum ep0_req -{ - USB_REQ_EP0_GET_PROTO_VER = 100, // get protocol version (PROTOCOL_VER), req = me, ind = 0, val = 0, len = 2 - USB_REQ_EP0_GET_STATUS, // 获取各工作线程状态, return EP0REPLYSTATUS. req = me, ind = 0, val = 0, len = sizeof(EP0REPLYSTATUS) - USB_REQ_EP0_RESET_BULK, // 关闭并重新打开BULK端点, return error number (uint32_t). req = me, ind = 0, val = 0, len = sizeof(uint32_t) - USB_REQ_EP0_CANCEL_CMD, // 取消当前指令的继续执行(一般用于中止大数据的传输). req = me, ind = 0, val = 0, len = sizeof(uint32_t) * 2 [(uint32_t)cmd + (uint32_t)pack-id] -}; -enum bulk_status -{ - BULK_STATUS_NOT_START = 0, // has not initialized - BULK_STATUS_IDLE, // wait IO - BULK_STATUS_IO, // in reading or writing - BULK_STATUS_ERROR, // error occurs - BULK_STATUS_RESET, // in reset(close and reopen) process -}; - -enum packet_cmd -{ - PACK_CMD_NULL, - - PAIR_COMMAND(PACK_CMD_HEART_BEAT), // notify peers you are still alive, receiver should reply the same pack - PAIR_COMMAND(PACK_CMD_INVALID), // reply when received an invalid packet - PAIR_COMMAND(PACK_CMD_SYNC), - - // attributes get/set, all content in PACK_BASE::payload should be in JSON style - all readonly attributes move to readonly SANE-options on 2023-03-20 - //PACK_CMD_ATTR_SYS_VER_GET = 10, // get system version on device, [in]: PACK_BASE, [out] PACK_BASE::payload - {"os":"linux", "ver":"4.4.194", ...} - //PACK_CMD_ATTR_FIRMWARE_VER_GET, // get firmware version, [in]: PACK_BASE, [out] PACK_BASE::payload - {"firmware":"G2393A1234", "CIS":"CIS-123", ...} - //PACK_CMD_ATTR_SERIAL_NUM_GET, // get device serial num, [in]: PACK_BASE, [out] PACK_BASE::payload - {"serial":"20221206001"} - //PACK_CMD_ATTR_SERIAL_NUM_SET, // set device serial num, [in]: PACK_BASE::payload - {"serial":"20221206001"}, [out] PACK_BASE - //PACK_CMD_ATTR_MAC_GET, // get mac address, [in]: PACK_BASE, [out] PACK_BASE::payload - {"mac":"12:34:56:78:9a:bc"} - //PACK_CMD_ATTR_IP_GET, // get ip address, [in]: PACK_BASE, [out] PACK_BASE::payload - {"ipv4":"192.168.1.123", "ipv6":"::1"} - //PACK_CMD_ATTR_HARDWARE_INFO_GET, // get hardwares information on device, [in]: PACK_BASE, [out] PACK_BASE::payload - {"CPU":"ARM x86", "mem":"16GB", ...} - //PACK_CMD_ATTR_HISTORY_COUNT_GET, // get history count, [in]: PACK_BASE, [out] PACK_BASE::payload - {"history-count":12345, ...} - //PACK_CMD_ATTR_ROLLER_COUNT_GET, // get roller count, [in]: PACK_BASE, [out] PACK_BASE::payload - {"roller-count":2345} - //PACK_CMD_ATTR_ROLLER_COUNT_SET, // set roller count, [in]: PACK_BASE::payload - {"roller-count":2345}, [out] PACK_BASE - - // configuration get/set - PACK_CMD_STATUS_ROGER = 100, // device -> host. PACK_BASE::result -> status - PAIR_COMMAND(PACK_CMD_SETTING_GET), // get all settings supported by the device, [in]: PACK_BASE, [out]: PACK_BASE::payload - configuration JSON, see SANE-configuration format - PAIR_COMMAND(PACK_CMD_SETTING_GET_CUR), // get current value of given setting, [in]: PACK_BASE::payload - (char*)name, [out]: PACK_BASE::payload - LPCFGVAL - PAIR_COMMAND(PACK_CMD_SETTING_SET), // set value of given setting, [in]: PACK_BASE::payload - LPCFGVAL, [out]: PACK_BASE::payload - LPCFGVAL - PAIR_COMMAND(PACK_CMD_SETTING_RESTORE), // restore given settings, [in]: PACK_BASE::payload - LPCFGVAL, [out]: PACK_BASE::payload - LPCFGVAL - - // scan command - 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 - PACK_CMD_SCAN_FINISHED_ROGER, // device -> host, PACK_BASE - 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 - //PAIR_COMMAND(PACK_CMD_SCAN_STATUS), // get scanner status, [in]: PACK_BASE, [out] PACK_BASE::result is status code - - // file operation - PACK_CMD_FILE_BASE = 300, - //PAIR_COMMAND(PACK_CMD_FILE_QUERY), // query file information, [in]: PACK_BASE::payload - (char*)file-path, [out] PACK_BASE::payload - LPFILEINFO - PAIR_COMMAND(PACK_CMD_FILE_READ_REQ), // read file content, [in]: PACK_BASE::payload - LPTXFILE, [out] PACK_BASE::payload - LPTXFILE - PAIR_COMMAND(PACK_CMD_FILE_WRITE_REQ), // write a file, [in]: PACK_BASE::payload - LPTXFILE, [out] PACK_BASE - PAIR_COMMAND(PACK_CMD_FILE_MOVE), // move/rename a file, [in]: PACK_BASE::payload - src\0dst\0\0, [out] PACK_BASE - PAIR_COMMAND(PACK_CMD_FILE_REMOVE), // delete a file, [in]: PACK_BASE::payload - (char*)file-path, [out] PACK_BASE - - // process operation - PACK_CMD_PROCESS_BASE = 400, - PAIR_COMMAND(PACK_CMD_PROCESS_START), // start a program [in]: PACK_BASE::payload - (char*)pe\0param\0\0, [out]: PACK_BASE::payload - (uint64_t)process-id on success or PACK_BASE on failure - PAIR_COMMAND(PACK_CMD_PROCESS_STOP), // kill a process [in]: PACK_BASE::payload - (char*)process-id, [out]: PACK_BASE - PAIR_COMMAND(PACK_CMD_PROCESS_REBOOT), // reboot system, [in]: PACK_BASE, [out]: PACK_BASE - //PAIR_COMMAND(PACK_CMD_PROCESS_EXEC_RESULT), // get result of a command, [in]: PACK_BASE::payload - (char*)command string, [out]: PACK_BASE::payload - (char*)execute result. popen(), fgets ... - //PAIR_COMMAND(PACK_CMD_PROCESS_QUERY), // query process information [in]: PACK_BASE::payload - (char*)process-id(-1 for all), [out]: LPPROCINFO - - PACK_CMD_TOKEN_GET = 900, // Obtain the token of the required command, [in] PACK_BASE, [out] - PACK_BASE::payload - LPOPERTOKEN -}; - -enum scanner_status -{ - SCANNER_STATUS_READY = 0, - SCANNER_STATUS_NOT_OPEN, - SCANNER_STATUS_LOST_CONNECT, - SCANNER_STATUS_RESET_BULK, - SCANNER_STATUS_START_SCANNING, // start ok, but scanning-thread not working - SCANNER_STATUS_SCANNING, // start ok, and scanning-thread is working - SCANNER_STATUS_SCAN_FINISHED, // not a persistance status - SCANNER_STATUS_BUSY, // doing task exclude scanning - SCANNER_STATUS_COVER_OPENNED, - SCANNER_STATUS_SLEEPING, - SCANNER_STATUS_COUNT_MODE, - SCANNER_STATUS_DOUBLE_FEEDED, - SCANNER_STATUS_PAPER_JAMMED, - SCANNER_STATUS_PAPER_ASKEW, - SCANNER_STATUS_FEED_FAILED, - SCANNER_STATUS_NO_PAPER, - SCANNER_STATUS_CFG_CHANGED, // PACK_BASE::payload - LPCFGVAL -}; - -enum img_format -{ - IMG_FMT_UNKNOWN = 0, // unknown format - IMG_FMT_TIFF, - IMG_FMT_BMP, - IMG_FMT_JPEG, - IMG_FMT_PNG, - IMG_FMT_SVG, - IMG_FMT_WEBP, - IMG_FMT_GIF, -}; -enum img_compression -{ - IMG_COMPRESSION_NONE = 0, - IMG_COMPRESSION_GROUP4, - IMG_COMPRESSION_RLE4, - IMG_COMPRESSION_RLE8, - IMG_COMPRESSION_LZW, - IMG_COMPRESSION_ZIP, -}; -enum img_status -{ - IMG_STATUS_OK = 0, - IMG_STATUS_DOUBLE, - IMG_STATUS_JAM, - IMG_STATUS_STAPLE, // staples on the paper - IMG_STATUS_SIZE_ERR, // size check failed - IMG_STATUS_DOGEAR, // paper has dogear -}; -enum data_type -{ - DATA_TYPE_BOOL = 0, // (bool*) - DATA_TYPE_INT1, // (uint8_t*) - DATA_TYPE_INT2, // (uint16_t*) - DATA_TYPE_INT4, // (uint32_t*) - DATA_TYPE_INT8, // (uint64_t*) - DATA_TYPE_FLOAT, // (double*) - DATA_TYPE_STRING, // (char*) with max_len space - DATA_TYPE_CUSTOM, -}; - -enum paper_side -{ - PAPER_SIDE_FRONT = 0, // single side, this is front - PAPER_SIDE_BACK, // single side, this is back - PAPER_SIDE_TOP, // VERT-compound sides, and front side is at top - PAPER_SIDE_BOTTOM, // VERT-compound sides, and front side is at bottom - PAPER_SIDE_LEFT, // HORZ-compound sides, and front side is at left - PAPER_SIDE_RIGHT, // HORZ-compound sides, and front side is at right -}; -enum rot_angle -{ - ROT_ANGLE_0 = 0, - ROT_ANGLE_90, - ROT_ANGLE_180, - ROT_ANGLE_270, -}; - -#pragma pack(push) -#pragma pack(1) -typedef struct _ep0_reply -{ - uint8_t in_status; // BULK-IN status, enum bulk_statu - uint8_t out_status; // BULK-OUT status, enum bulk_statu - uint16_t in_err; // valid if in_statu == BULK_STATU_ERROR - uint16_t out_err; // valid if out_statu == BULK_STATU_ERROR - uint16_t task_cnt; // tasks in command queue - uint32_t task_cmd; // the cmd of the task thread is doing - uint32_t task_pack_id; // packet id of the cmd - uint32_t task_required_bytes; // required byte of this packet - uint32_t packets_to_sent; // how many packets in sent queue - uint32_t bytes_to_sent; // how many bytes data is waiting for be sent in one replying packet -}EP0REPLYSTATUS, *LPEP0REPLYSTATUS; - -typedef struct _pack_base // A piece of data has only one header -{ - uint32_t size : 16; // bytes of this structure - uint32_t result : 16; // error code in reply packet, be ZERO in command packet - uint32_t cmd; // packet command - uint32_t pack_id; // maintain by the initiator, the reply use the same id - uint32_t payload_len; // total bytes of payload of this packet (the data in the range will sent in ONE 'write') - char payload[0]; // payloads, according to 'cmd' - - STRUCT_CONSTRUCTOR(_pack_base) -}PACK_BASE, * LPPACK_BASE; -#define BASE_PACKET_REPLY(reply, command, id, err) \ - (reply).size = sizeof(reply); \ - (reply).result = err; \ - (reply).cmd = command; \ - (reply).pack_id = id; \ - (reply).payload_len = 0; - - -typedef struct _config_val -{ - uint8_t type; // same as SANE_Value_Type - uint8_t name_off; // name offset of the option in data, end with '\0' - uint8_t val_off; // option value offset in data - uint8_t after_do; // see SANE_INFO_xxx in sane.h - uint16_t val_size; // real size of value - uint32_t err; // set result - char data[0]; // contains value and name. fetch them according name_off and val_off members. -}CFGVAL, *LPCFGVAL; - -typedef struct _img_pos -{ - uint64_t paper_ind : 32; // paper index in this turn/start, based ZERO. (image-collector set) - uint64_t new_img : 1; // 0 - partial data; 1 - new image data. (image-collector set) - 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 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 - uint64_t reserved : 6; // reserved - - STRUCT_CONSTRUCTOR(_img_pos) -}IMGPOS, * LPIMGPOS; -typedef struct _pack_img -{ - IMGPOS pos; // image pos info ... - uint32_t width; // image width in pixel. (image-collector set) - uint32_t height; // image height in pixel. (image-collector set) - uint32_t resolution_x; // image horizontal reolution. (image-collector set) - uint32_t resolution_y; // image vertical reolution. (image-collector set) - uint32_t channels : 6; // image channels per pixel. (image-collector set) - uint32_t format : 6; // image format, see 'img_format'. (image-collector set) - uint32_t bpp : 6; // bits per pixel. (image-collector set) - uint32_t bppc : 6; // bits per pixel in this channel, equal to 'bpp' if pos.channel_ind == 0x0f. (image-collector set) - uint32_t compression : 6; // image data compression, see 'img_compression'. (image-collector set) - 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) - - STRUCT_CONSTRUCTOR(_pack_img) -}PACKIMAGE, * LPPACKIMAGE; - -typedef struct _oper_token -{ - uint32_t type; // token type - char data[128]; // token data -}OPERTOKEN, * LPOPERTOKEN; - -typedef struct _tx_file -{ - uint64_t size; // total size - uint64_t offset; // offset in the file - char path[2]; // file full path-name -}TXFILE, *LPTXFILE; -typedef struct _file_info -{ - OPERTOKEN token; // operation token, returned by command PACK_CMD_TOKEN_GET - uint64_t size; // file size - uint16_t name_len; // bytes of file name string - uint16_t create_time_len; // bytes of create time string: '2022-12-07 12:34:56.789', or target file path in command PACK_CMD_FILE_MOVE - uint16_t modify_time_len; - uint16_t version_len; // bytes of version string - char data[0]; // 4 parts: path-file(name_len) + create-time(create_time_len) + modify-time(modify_time_len) + version(version_len) - // or 5 parts in command PACK_CMD_FILE_WRITE, add content at the last part of bytes 'size' - - STRUCT_CONSTRUCTOR(_file_info) -}FILEINFO, * LPFILEINFO; - -typedef struct _proc_info -{ - OPERTOKEN token; // operation token, returned by command PACK_CMD_TOKEN_GET - uint32_t count; // number of elements in array proc - struct _info - { - uint16_t len; // bytes of this element, include this head - uint64_t pid; // process id - uint64_t ppid; // parent process id - uint64_t start; // started time in ns from 1970-01-01 00:00:00 - uint64_t mem; // memory usage, in bytes - uint64_t cpu_clk; // cpu clock - char path_name[4]; - }proc[1]; - - STRUCT_CONSTRUCTOR(_proc_info) -}PROCINFO, * LPPROCINFO; -#pragma pack(pop) - -//////////////////////////////////////////////////////////////////////////////////////////////// -// configurations ... -// -// 1 - App has whole set, group definitions -// -// 2 - device provides sub-set, or a customizing item -// diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/referer.h b/device/gxx-linux/testusb/usb-rk3399/src/common/referer.h deleted file mode 100644 index 368e6bd..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/referer.h +++ /dev/null @@ -1,187 +0,0 @@ -#pragma once - -// Objects life management -// -// created on 2022-11-29 -// - -// #include -#include -#include - -#if defined(WIN32) || defined(_WIN64) -#define WAIT_INFINITE INFINITE -#define FSEEK _fseeki64 -#define FTELL _ftelli64 -#define USER_DIR "LOCALAPPDATA" -#define PATH_SEPARATOR "\\" - -struct _time_val -{ - time_t tv_sec; /* Seconds. */ - time_t tv_usec; /* Microseconds. */ -}; -typedef struct _time_val TIMEV; - -struct timezone -{ - int tz_minuteswest; /* Minutes west of GMT. */ - int tz_dsttime; /* Nonzero if DST is ever in effect. */ -}; -extern int gettimeofday(TIMEV* tv, struct timezone* tz); -#else -#include -#include -#include -typedef struct timeval TIMEV; -#define WAIT_INFINITE 0 -#define FSEEK fseek -#define FTELL ftell -#define USER_DIR "HOME" -#define PATH_SEPARATOR "/" - -#endif - -#define ALIGN_INT(val, n) ((((val) + (n) - 1) / (n)) * (n)) - -#define SIZE_KB(n) ((n) * 1024) -#define SIZE_MB(n) SIZE_KB((n) * 1024) -#define SIZE_GB(n) SIZE_MB((n) * 1024) - -#define SEC_2_MS(s) ((s) * 1000) -#define MSEC_2_US(ms) ((ms) * 1000) -#define USEC_2_NS(us) ((us) * 1000) -#define SEC_2_US(s) MSEC_2_US(SEC_2_MS(s)) -#define SEC_2_NS(s) USEC_2_NS(MSEC_2_US(SEC_2_MS(s))) -#define MSEC_2_NS(ms) USEC_2_NS(MSEC_2_US(ms)) - -#define RETURN_ENUM_STR(v, e) \ - if(v == e) \ - return #e; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -typedef std::mutex MUTEX; -typedef std::lock_guard LOCKER; - -// object life referer -// -// derived from 'refer' if your class used in multi-threads -// -class refer -{ - volatile int32_t ref_; - MUTEX mutex_; - -protected: - refer(); - virtual ~refer(); - - virtual void on_born(void); - virtual void on_dead(void); - -public: - virtual int32_t add_ref(void); - virtual int32_t release(void); -}; - -class chronograph -{ - TIMEV bgn_; - -public: - chronograph(); - ~chronograph(); - - static bool now(TIMEV* tv); - static bool now(uint64_t* seconds, uint64_t* u_seconds); - static std::string now(bool with_ms = true/*whether with milliseconds*/); // return '2022-11-30 10:38:42.123', no '.123' if with_ms was false - -public: - uint64_t elapse_s(void); - uint64_t elapse_ms(void); - uint64_t elapse_us(void); - void reset(void); -}; - -template -class thread_pool : public refer -{ - typedef struct _thrd - { - uint32_t id; - std::shared_ptr thread; - }THRD; - T* obj_; - std::vector threads_; - uint32_t id_; - - -public: - thread_pool(T* obj) : obj_(obj), id_(1) - {} - -protected: - virtual ~thread_pool() - {} - -public: - template - uint32_t thread_new(void(T::* thrd)(Args ...), Args ... args) // return thread ID (not pthread_t), used in thread_stop function - { - THRD t; - - t.id = id_++; - t.thread.reset(new std::thread(thrd, obj_, args ...)); - threads_.push_back(t); - - return t.id; - } - bool thread_stop(uint32_t id = -1) - { - bool ret = true; - if (id == -1) - { - for (auto& v : threads_) - { - if (v.thread.get() && v.thread->joinable()) - v.thread->join(); - v.thread.reset(); - } - threads_.clear(); - } - else - { - ret = false; - for (int i = 0; i < threads_.size(); ++i) - { - if (threads_[i].id == id) - { - ret = true; - if (threads_[i].thread.get() && threads_[i].thread->joinable()) - threads_[i].thread->join(); - threads_[i].thread.reset(); - threads_.erase(threads_.begin() + i); - break; - } - } - } - - return ret; - } -}; - - -template -T swap_half(T v) -{ - T mask = (1 << (sizeof(T) * 4)) - 1, - h = v & mask; - - v >>= sizeof(T) * 4; - v &= mask; - h <<= sizeof(T) * 4; - v |= h; - - return v; -} diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/sys_util.cpp b/device/gxx-linux/testusb/usb-rk3399/src/common/sys_util.cpp deleted file mode 100644 index e06b2d1..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/sys_util.cpp +++ /dev/null @@ -1,854 +0,0 @@ -#include "sys_util.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "log_util.h" - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// sys utility - -namespace sys_util -{ - static bool find_module(const char* path, bool is_dir, void* param) - { - std::string* para = (std::string*)param; - - if (para[0].empty()) - { - const char* now = getenv("PWD"); - bool found = strstr(path, now) == path; - - if(found) - { - found = path[strlen(now)] == '/' && strstr(path + strlen(now) + 1, "/") == nullptr; - } - if(found || para[1].empty()) - para[1] = path; - - return !found; - } - else - { - const char* name = strrchr(path, '/'); - if (name++ == nullptr) - name = path; - if (strstr(name, para[0].c_str())) - { - para[1] = path; - - return false; - } - - return true; - } - } - typedef struct _enum_proc_cb - { - bool process; - bool(*on_found)(uint64_t pid, const char* path_name, void* param); - void* param; - }ENPROCCB, * LPENPROCCB; - static bool found_process(const char* path, bool is_dir, void* param) - { - LPENPROCCB cb = (LPENPROCCB)param; - const char* id = strrchr(path, '/'); - uint64_t pid = 0; - std::string path_name(""); - - if (id++ == nullptr) - { - id = path; - } - while (*id) - { - if (*id < '0' || *id > '9') - break; - - pid *= 10; - pid += *id - '0'; - id++; - } - if (*id || pid == 0) - return true; - - if (cb->process) - { - path_name = get_module_path(nullptr, pid); - id = path_name.c_str(); - } - else - { - // get start address of pid to path_name - id = 0; - } - - return cb->on_found(pid, id, cb->param); - } - static bool on_stack_line_read(char* line, void* param) - { - LPENPROCCB cb = (LPENPROCCB)param; - std::string m(line); - uint64_t off = 0; - size_t pos = m.find("]"); - - if (pos++ != std::string::npos) - m.erase(0, pos); - sys_util::trim_left(m); - pos = m.find("+0x"); - if (pos != std::string::npos) - { - off = from_hex_str(m.c_str() + pos + 3); - m.erase(pos); - } - - return cb->on_found(off, m.c_str(), cb->param); - } - - int32_t enum_modules(bool(*on_found)(const char* path_module_name, bool is_dir, void* param),// return false to stop enumeratin - void* param, // user defined data, passed into callback on_found - unsigned pid // process id, -1 is self - ) // return errno - { - char path[128] = { 0 }; - - if (pid == -1) - pid = getpid(); - sprintf(path, "/proc/%u/map_files/", pid); - - return enum_files(path, on_found, param, false); - } - - int32_t enum_files(const char* dir, // dir path - bool(*on_found)(const char* path_name, bool is_dir, void* param), // return false to stop enumeratin - void* param // user defined data, passed into callback on_found - , bool recursive - ) // return errno - { - int32_t ret = 0; - DIR* pdir = nullptr; - struct dirent* ent = nullptr; - - pdir = opendir(dir); - if (!pdir) - return errno; - - while ((ent = readdir(pdir))) - { - if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) - continue; - - std::string file(dir); - - file += "/"; - file += ent->d_name; - if ((ent->d_type & DT_DIR) == 0) - { - file = read_link(file.c_str()); - if(file.empty()) - file = std::string(dir) + "/" + ent->d_name; - } - if (!on_found(file.c_str(), ent->d_type & DT_DIR, param)) - { - ret = 0x5e17; - break; - } - - if ((ent->d_type & DT_DIR) && recursive) - { - std::string sub(dir); - sub += "/"; - sub += ent->d_name; - ret = enum_files(sub.c_str(), on_found, param, recursive); - if (ret == 0x5e17) - break; - } - } - closedir(pdir); - - return ret == 0x5e17 ? 0 : ret; - } - - int32_t enum_processes(bool(*on_found)(uint64_t pid, const char* path_name, void* param), void* param) - { - ENPROCCB cb; - - cb.on_found = on_found; - cb.param = param; - cb.process = true; - - return enum_files("/proc", found_process, &cb, false); - } - uint32_t enum_threads(uint64_t pid, bool(*on_found)(uint64_t tid, void* start_addr, void* param), void* param) - { - ENPROCCB cb; - - cb.process = false; - cb.param = param; - *(void**)&cb.on_found = *(void**)&on_found; - - return enum_files(("/proc/" + std::to_string(pid) + "/task").c_str(), found_process, &cb, false); - } - uint32_t get_thread_callstack(uint64_t pid, uint64_t tid, bool(*on_found)(uint64_t off, const char* module, void* param), void* param) - { - ENPROCCB cb; - - cb.process = false; - cb.param = param; - *(void**)&cb.on_found = *(void**)&on_found; - - return read_line(("/proc/" + std::to_string(pid) + "/task/" + std::to_string(tid) + "/stack").c_str(), on_stack_line_read, &cb); - } - uint32_t read_line(const char* file, bool(*on_line)(char* line, void* param), void* param) - { - FILE* src = fopen(file, "rb"); - int err = 0; - - if (!src) - return errno; - - size_t ll = 1024; - char* line = new char[ll]; - while (fgets(line, ll - 1, src)) - { - if (!on_line(line, param)) - break; - - memset(line, 0, ll); - } - err = errno; - delete[] line; - fclose(src); - - return err; - } - - std::string get_module_path(const char* module_name, unsigned pid) // get module full path, nullptr is for main-exe - { - std::string param[] = { module_name ? module_name : "", "" }; - - enum_modules(find_module, param, pid); - - return param[1]; - } - std::string read_link(const char* lnk) - { - char path[512] = { 0 }; - - readlink(lnk, path, sizeof(path) - 1); - - return path; - } - size_t get_page_size(void) - { - size_t size = sysconf(_SC_PAGESIZE); - - if (size < 1024 || (size & 0x0fe0000ff)) // nKB && < 16MB - size = getpagesize(); - - return size; - } - bool create_folder(const char* dir) - { - bool ret = mkdir(dir, S_IREAD | S_IWRITE | S_IEXEC) == 0 || errno == EEXIST; - - if(errno == ENOENT) - { - std::string path(dir), cur(""); - size_t pos = path.find("/", 1); - - while(pos != std::string::npos) - { - ret = mkdir(path.substr(0, pos).c_str(), S_IREAD | S_IWRITE | S_IEXEC) == 0 || errno == EEXIST; - if(!ret) - { - printf("mkdir(%s) = %d(%s)\n", path.substr(0, pos).c_str(), errno, strerror(errno)); - break; - } - pos = path.find("/", pos + 1); - } - if(ret) - ret = mkdir(path.c_str(), S_IREAD | S_IWRITE | S_IEXEC) == 0; - } - - return ret; - } - - int32_t get_memory_info(uint64_t* total, uint64_t* available) - { - if (!total && !available) - return 0; - - char line[128] = { 0 }; - FILE* src = fopen("/proc/meminfo", "rb"); - int32_t count = total && available ? 2 : 1; - unsigned long val = 0; - - if (!src) - return log_cls::log_when_err(-1, "fopen('/proc/meminfo', 'rb')", LOG_LEVEL_FATAL); - - while (fgets(line, sizeof(line) - 1, src)) - { - if (sscanf(line, "MemTotal: %ld", &val)) - { - if (total) - { - *total = val * 1024; - if (--count == 0) - break; - } - } - else if (sscanf(line, "MemFree: %ld", &val)) - { - if (available) - { - *available = val * 1024; - if (--count == 0) - break; - } - } - } - - fclose(src); - - return 0; - } - std::string format_readable_bytes(uint64_t bytes) - { - std::string str("\0", 80); - - if (bytes >= SIZE_GB(1)) - { - double v = bytes * 1.0f / (SIZE_GB(1)); - size_t pos = 0; - - sprintf(&str[0], "%.2fGB", v); - pos = str.find("."); - while (pos > 3) - { - pos -= 3; - str.insert(pos, ","); - } - } - else if (bytes >= SIZE_MB(1)) - { - double v = bytes * 1.0f / (SIZE_MB(1)); - sprintf(&str[0], "%.2fMB", v); - } - else if (bytes >= SIZE_KB(1)) - { - double v = bytes * 1.0f / (SIZE_KB(1)); - sprintf(&str[0], "%.2fKB", v); - } - else - { - sprintf(&str[0], "%uB", (unsigned)bytes); - } - - return str; - } - std::string get_command_output(const char* cmd, uint16_t max_line_len, bool one_line) - { - FILE* src = popen(cmd, "r"); - std::string ret(""); - - if (src) - { - char* buf = new char[max_line_len + 4]; - if (buf) - { - memset(buf, 0, max_line_len + 4); - fgets(buf, max_line_len, src); - ret = buf; - while (!one_line && fgets(buf, max_line_len, src)) - ret += "\n" + std::string(buf); - - delete[] buf; - } - - pclose(src); - } - - return ret; - } - int get_disk_size(const char* path, uint64_t* total, uint64_t* avail, uint64_t* block_size) - { - std::string dir(path ? path : ""); - struct statfs disk; - size_t pos = dir.rfind('/'); - - if (dir.empty() || dir[0] == '.' || pos == std::string::npos) - { - char self[256] = { 0 }; - - if (readlink("/proc/self/exe", self, sizeof(self) - 1) == -1) - return errno; - - dir = self; - } - pos = dir.rfind('/'); - if (pos != std::string::npos && pos > 0) - dir.erase(pos); - - if (statfs(dir.c_str(), &disk) == -1) - return errno; - - if (total) - *total = disk.f_blocks * disk.f_bsize; - if (avail) - *avail = disk.f_bsize * disk.f_bavail; - if (block_size) - *block_size = disk.f_bsize; - - return 0; - } - - static bool is_char_in(const char* str, char ch) - { - if (ch == 0) - return false; - - while (*str) - { - if (*str++ == ch) - return true; - } - - return false; - } - bool trim_left(std::string& str, const char* space) - { - int off = 0; - - for (; off < str.length(); ++off) - { - if (!is_char_in(space, str[off])) - break; - } - if (off) - str.erase(0, off); - - return off > 0; - } - bool trim_right(std::string& str, const char* space) - { - int off = str.length() - 1; - - for (; off >= 0; --off) - { - if (!is_char_in(space, str[off])) - break; - } - if (off < str.length() - 1) - { - str.erase(off + 1); - return true; - } - - return false; - } - uint64_t from_hex_str(const char* hex, const char** end) - { - uint64_t val = 0; - - for (int i = 0; i < 16; ++i) - { - if (*hex >= '0' && *hex <= '9') - { - val <<= 4; - val += *hex - '0'; - } - else if (*hex >= 'a' && *hex <= 'f') - { - val <<= 4; - val += *hex - 'a' + 10; - } - else if (*hex >= 'A' && *hex <= 'F') - { - val <<= 4; - val += *hex - 'A' + 10; - } - else - { - break; - } - hex++; - } - - if (end) - *end = hex; - - return val; - } - - static uint64_t from_dec_str(const char* str, const char** end) - { - uint64_t val = 0; - - for(int i = 0; *str && i < 19; ++i, ++str) - { - if(*str >= '0' && *str <= '9') - { - val *= 10; - val += *str - '0'; - } - else - break; - } - if(end) - *end = str; - - return val; - } - static uint64_t from_oct_str(const char* str, const char** end) - { - uint64_t val = 0; - - for(int i = 0; *str && i < 21; ++i, ++str) - { - if(*str >= '0' && *str <= '7') - { - val *= 8; - val += *str - '0'; - } - else - break; - } - if(end) - *end = str; - - return val; - } - static uint64_t from_bin_str(const char* str, const char** end) - { - uint64_t val = 0; - - for(int i = 0; *str && i < 64; ++i, ++str) - { - if(*str >= '0' && *str <= '1') - { - val *= 2; - val += *str - '0'; - } - else - break; - } - if(end) - *end = str; - - return val; - } - uint64_t to_int(const char* str, const char** end) - { - if(!str || *str == 0) - { - if(end) - *end = str; - - return 0; - } - - if(strstr(str, "0x") == str) - return from_hex_str(str + 2, end); - - if(str[strlen(str) - 1] == 'h' || str[strlen(str) - 1] == 'H') - return from_hex_str(str, end); - if(str[strlen(str) - 1] == 'o' || str[strlen(str) - 1] == 'O') - return from_oct_str(str, end); - if(str[strlen(str) - 1] == 'b' || str[strlen(str) - 1] == 'B') - return from_bin_str(str, end); - - bool hex = false; - for(int i = 0; str[i]; ++i) - { - if(str[i] < '0') - break; - if(str[i] > '9') - { - if((str[i] >= 'a' && str[i] <= 'f') || - (str[i] >= 'A' && str[i] <= 'F')) - hex = true; - break; - } - } - - return hex ? from_hex_str(str, end) : from_dec_str(str, end); - } - - /* iconv_open language options: - - Europe: - ASCII, ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16}, KOI8-R, KOI8-U, KOI8-RU, - CP{1250,1251,1252,1253,1254,1257}, CP{850,866}, - Mac{Roman,CentralEurope,Iceland,Croatian,Romania}, - Mac{Cyrillic,Ukraine,Greek,Turkish}, Macintosh - - Semitic: - ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic} - - Janpanese: - EUC-JP, SHIFT-JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1 - - Chinese: - EUC-CN, HZ, GBK, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, ISO-2022-CN, ISO-2022-CN-EXT - - Korean: - EUC-KR, CP949, ISO-2022-KR, JOHAB - - Armenian: - ARMSCII-8 - - Georgian: - Georgian-Academy, Georgian-PS - - Thai: - TIS-620, CP874, MacThai - - Laos: - MuleLao-1, CP1133 - - Vietnam: - VISCII, TCVN, CP1258 - - Special: - HP-ROMAN8, NEXTSTEP - - Full Unicode: - UTF-8 - UCS-2, UCS-2BE, UCS-2LE - UCS-4, UCS-4BE, UCS-4LE - UTF-16, UTF-16BE, UTF-16LE - UTF-32, UTF-32BE, UTF-32LE - UTF-7 - JAVA - */ - std::string transform_between_gbk_and_utf8(const char* in, bool to_utf8, int *err) - { - size_t len = strlen(in) + 8, ol = len * 2; - char *buf = (char*)malloc(len), *oper = buf, *out = nullptr, *oper1 = nullptr; - iconv_t conv; - - memset(buf, 0, len); - strcpy(buf, in); - if(to_utf8) - conv = iconv_open("UTF-8", "GBK"); - else - conv = iconv_open("GBK", "UTF-8"); - if(conv == (iconv_t)-1) - { - if(err) - *err = errno; - - free(buf); - - return ""; - } - - oper1 = out = (char*)malloc(ol); - memset(out, 0, ol); - len -= 8; - if(iconv(conv, &oper, &len, &oper1, &ol)) - { - if(err) - *err = errno; - } - else if(err) - *err = 0; - - std::string ret(out); - - free(buf); - free(out); - iconv_close(conv); - - return std::move(ret); - } - std::string transform_between_utf16_and_utf8(const char* in, size_t bytes, bool to_utf8) - { - static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - std::string ret(""); - - if(to_utf8) - { - unsigned short *uc = *(unsigned short**)&in, val = 0; - for(size_t i = 0; i < bytes / 2; ++i, ++uc) - { - val = *uc; - if ((*uc>=0xDC00 && *uc<=0xDFFF) || *uc==0) break; /* check for invalid. */ - - if (*uc>=0xD800 && *uc<=0xDBFF) /* UTF16 surrogate pairs. */ - { - unsigned short uc2 = uc[1]; - if (uc2 < 0xDC00 || uc2 > 0xDFFF) break; /* invalid second-half of surrogate. */ - val = 0x10000 + (((*uc & 0x3FF) << 10) | (uc2 & 0x3FF)); - } - - int len = 4; - char buf[4] = {0}, *ptr2 = buf; - if (val<0x80) len=1;else if (val<0x800) len=2;else if (val<0x10000) len=3; ptr2+=len; - - switch (len) { - case 4: *--ptr2 =((val | 0x80) & 0xBF); val >>= 6; - case 3: *--ptr2 =((val | 0x80) & 0xBF); val >>= 6; - case 2: *--ptr2 =((val | 0x80) & 0xBF); val >>= 6; - case 1: *--ptr2 =(val | firstByteMark[len]); - } - ret += std::string(buf, len); - } - } - else - { - char* unic = (char*)malloc(strlen(in) * 3 + 8); - unsigned char * cur = (unsigned char*)unic; - - while (*cur = *in++) - { - if ((*cur & 0x0f0) == 0x0e0) - { - if (((unsigned char)in[0] & 0x0c0) == 0x80 && - ((unsigned char)in[1] & 0x0c0) == 0x80) - { - const char* hex = "0123456789ABCDEF"; - unsigned short us = *cur & 0x0f; - us <<= 6; - us += in[0] & 0x3f; - us <<= 6; - us += in[1] & 0x3f; - - *cur++ = '\\'; - *cur++ = 'u'; - cur[3] = hex[us & 0x0f]; - us >>= 4; - cur[2] = hex[us & 0x0f]; - us >>= 4; - cur[1] = hex[us & 0x0f]; - us >>= 4; - cur[0] = hex[us & 0x0f]; - cur += 3; - in += 2; - } - } - cur++; - } - *cur++ = 0; - ret = std::string(unic, (char*)cur - unic); - free(unic); - } - - return std::move(ret); - } - - std::string to_abs_path(const char* base, const char* rel_path) - { - if(*rel_path == '/') - return rel_path; - - std::string b(base), r(rel_path); - size_t pos = 0; - - while(b.length() && b[b.length() - 1] == '/') - b.erase(b.length() - 1); - - while(r[0] == '.') - { - if(r[1] == '/') - r.erase(0, 2); - else if(r[1] == '.' && r[2] == '/') - { - pos = b.rfind('/'); - if(pos == std::string::npos) - break; - b.erase(pos); - r.erase(0, 3); - } - else - break; - } - - b += "/" + r; - - return std::move(b); - } - std::string to_rel_path(const char* base, const char* abs_path) - { - if(*abs_path != '/') - return abs_path; - - std::string rel(""), b(base), a(abs_path); - size_t pos = 0; - - while(b.length() && b[b.length() - 1] == '/') - b.erase(b.length() - 1); - - while(a.find(b) == std::string::npos) - { - rel += "../"; - pos = b.rfind('/'); - if(pos == 0) - break; - b.erase(pos - 1); - } - if(rel.empty()) - rel = "./"; - - return std::move(rel + a); - } - - const char* pick_simple_block(const char* head, char end) - { - const char* tail = head + 1; - int cnt = 1; - - while(*tail) - { - if(*tail == end) - { - cnt--; - if(cnt == 0) - break; - } - else if(*tail == *head) - { - cnt++; - } - else if(*tail == '\\') - { - tail++; - if(*tail == 0) - break; - } - tail++; - } - - return cnt == 0 ? tail : nullptr; - } - - bool now(struct timeval* tv) - { - struct timezone tz = { 0 }; - bool ok = gettimeofday(tv, &tz) == 0; - - // tv->tv_sec -= 60 * tz.tz_minuteswest; - - return ok; - } - uint64_t thread_id(const std::thread::id& tid) - { - return (uint64_t)pthread_self(); - - std::stringstream ss; - - ss << tid; - - return std::stoull(ss.str()); - } -} - diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/sys_util.h b/device/gxx-linux/testusb/usb-rk3399/src/common/sys_util.h deleted file mode 100644 index b89c9e4..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/sys_util.h +++ /dev/null @@ -1,106 +0,0 @@ -#pragma once - -// Objects life management -// -// created on 2022-11-29 -// - -#include -#include - - -namespace sys_util -{ - int32_t enum_modules(bool(*on_found)(const char* path_module_name, bool is_dir, void* param),// return false to stop enumeratin - void* param, // user defined data, passed into callback on_found - unsigned pid = -1 // process id, -1 is self - ); // return errno - - int32_t enum_files(const char* dir // dir path - , bool(*on_found)(const char* path_name, bool is_dir, void* param)// return false to stop enumeratin - , void* param // user defined data, passed into callback on_found - , bool recursive = true // walk recursive - ); // return errno - int32_t enum_processes(bool(*on_found)(uint64_t pid, const char* path_name, void* param), void* param); - uint32_t enum_threads(uint64_t pid, bool(*on_found)(uint64_t tid, void* start_addr, void* param), void* param); - uint32_t get_thread_callstack(uint64_t pid, uint64_t tid, bool(*on_found)(uint64_t off, const char* module, void* param), void* param); - uint32_t read_line(const char* file, bool(*on_line)(char* line, void* param), void* param); - - std::string get_module_path(const char* module_name = nullptr - , unsigned pid = -1); // get module full path, nullptr is for main-exe - std::string read_link(const char* lnk); - size_t get_page_size(void); - bool create_folder(const char* dir); - - // Function: pick single-line info file data, return count of set-value variable - // - // Parameters: file - full path of local file - // - // line_max - max bytes of a line in file 'file' - // - // fmt - line fromat string, e.g. "model name : %60[\x20-\x7e]", "MemoryTotal: %ld", "address sizes : %d bits physical, %d bits virtual", ... - // - // args - variable list - // - // Return: count of the variable which got the value - template - int32_t get_inf_file_data(const char* file, size_t line_max, const char* fmt, Args ... args) - { - std::string buf("\0", line_max + 8); - FILE* src = fopen(file, "rb"); - int32_t count = 0; - - if (!src) - return 0; - - while (fgets(&buf[0], line_max, src)) - { - count = sscanf(&buf[0], fmt, args ...); - if (count > 0) - break; - } - fclose(src); - - return count; - } - - int32_t get_memory_info(uint64_t* total, uint64_t* available); - std::string format_readable_bytes(uint64_t bytes); // convert to readable text: 512B, 1.21KB, 1.10MB, 3.45GB, 1,234.56GB ... - std::string get_command_output(const char* cmd, uint16_t max_line_len = 256, bool one_line = true); - int get_disk_size(const char* path, uint64_t* total, uint64_t* avail, uint64_t* block_size); - - // trim string, return whether space trimmed - bool trim_left(std::string& str, const char* space = " \t"); - bool trim_right(std::string& str, const char* space = " \t"); - uint64_t from_hex_str(const char* hex, const char** end = nullptr); // convert 0x100 to 256. parameter 'end' to receive the stopped position - - // Function: convert number string to integer, support hex, dec, oct and bin - // - // Parameter: str - number string. - // 0x.../...h: as hexadecimal - // ...o: as octonary - // ...b: as binary - // ...: as decimal, or as hexadecimal if has hex letter - // - // end - to receive the ending point when covert over - // - // Return: integer, default is ZERO, you should check the ending point when this value returned - uint64_t to_int(const char* str, const char** end = nullptr); - - std::string transform_between_gbk_and_utf8(const char* in, bool to_utf8, int* err = nullptr); - std::string transform_between_utf16_and_utf8(const char* in, size_t bytes, bool to_utf8); - - std::string to_abs_path(const char* base, const char* rel_path); - std::string to_rel_path(const char* base, const char* abs_path); - - // Function: pick simple block in pair chars - // - // Parameter: head - beginning of the string, and the first character is the beginning char - // - // end - ending character of the block - // - // Return: the last positoin of the block (*ret = end), or nullptr if not matched - const char* pick_simple_block(const char* head, char end); - - uint64_t thread_id(const std::thread::id& tid); -} diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/usb_io.cpp b/device/gxx-linux/testusb/usb-rk3399/src/common/usb_io.cpp deleted file mode 100644 index fa9e35c..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/usb_io.cpp +++ /dev/null @@ -1,790 +0,0 @@ -#include "usb_io.h" - -#include -#include -#include -#include -#include "../../inc/logs_out.h" -#include "sys_util.h" -#include "log_util.h" - -// #define TEST - -async_usb_gadget::async_usb_gadget(usb_gadget* gadget, std::function unhandled_ep0 - , std::function cmd_handler) - : gadget_(gadget), unhandled_ep0_(unhandled_ep0), handle_cmd_(cmd_handler), threads_(new thread_pool(this)) -{ - wait_ep0_ = new linux_event("wait_ep0"); - memset((void*)&status_, 0, sizeof(status_)); - memset((void*)&ep0_status_, 0, sizeof(ep0_status_)); - - threads_->thread_new(&async_usb_gadget::thread_pump_task); - thread_ep0_id_ = threads_->thread_new(&async_usb_gadget::thread_read_ep0); - threads_->thread_new(&async_usb_gadget::thread_check_ep0_status); -} - -async_usb_gadget::~async_usb_gadget() -{ - stop(); - if(thread_restart_id_ != -1) - threads_->thread_stop(thread_restart_id_); - threads_->release(); - wait_ep0_->release(); -} - -const char* async_usb_gadget::ep0_status_desc(int ep0_status, char* unk_buf/*>= 20 bytes*/) -{ - RETURN_ENUM_STR(ep0_status, EP0_STATUS_IDLE); - RETURN_ENUM_STR(ep0_status, EP0_STATUS_READ_DATA); - RETURN_ENUM_STR(ep0_status, EP0_STATUS_READ_INVAL_DATA); - RETURN_ENUM_STR(ep0_status, EP0_STATUS_HANDLE_CMD); - - sprintf(unk_buf, "Unknown status (%d)", ep0_status); - - return unk_buf; -} -void async_usb_gadget::set_ep0_status(uint32_t id, int status, int data) -{ - LOCKER lock(ep0_status_lock_); - - ep0_status_.id = id; - ep0_status_.status = status; - ep0_status_.data = data; -} -void async_usb_gadget::get_ep0_status(uint32_t* id, int* status, int* data) -{ - LOCKER lock(ep0_status_lock_); - - if (id) - *id = ep0_status_.id; - if (status) - *status = ep0_status_.status; - if (data) - *data = ep0_status_.data; -} - -int async_usb_gadget::wait_fd_event(int fd, int to_ms) -{ - struct timeval timeout, *pto = NULL; - fd_set read_set; - int ret = 0; - - FD_ZERO(&read_set); - FD_SET(fd, &read_set); - if (to_ms != -1) - { - timeout.tv_sec = to_ms / 1000; - timeout.tv_usec = (to_ms % 1000) * 1000; - pto = &timeout; - } - ret = select(fd + 1, &read_set, NULL, NULL, pto); - - return ret; -} - -int async_usb_gadget::open_bulk(void) -{ - int err = 0; - if (gadget_->ep_handles[EP_DESCRIPTOR_IN] < 0) - { - gadget_->ep_handles[EP_DESCRIPTOR_IN] = open(gadget_->ep_path[EP_DESCRIPTOR_IN], O_RDWR); - err = gadget_->ep_handles[EP_DESCRIPTOR_IN] == -1 ? errno : 0; - log_cls::log(LOG_LEVEL_ALL, "Open endpoint(%s) = %d (err = %d)\n", gadget_->ep_path[EP_DESCRIPTOR_IN], gadget_->ep_handles[EP_DESCRIPTOR_IN], err); - if(gadget_->ep_handles[EP_DESCRIPTOR_IN] >= 0) - { - status_.in_status = BULK_STATUS_IDLE; - thread_bulk_in_id_ = threads_->thread_new(&async_usb_gadget::thread_write_bulk); - } - } - if (gadget_->ep_handles[EP_DESCRIPTOR_OUT] < 0) - { - gadget_->ep_handles[EP_DESCRIPTOR_OUT] = open(gadget_->ep_path[EP_DESCRIPTOR_OUT], O_RDWR); - err = gadget_->ep_handles[EP_DESCRIPTOR_OUT] == -1 ? errno : 0; - log_cls::log(LOG_LEVEL_ALL, "Open endpoint(%s) = %d (err = %d)\n", gadget_->ep_path[EP_DESCRIPTOR_OUT], gadget_->ep_handles[EP_DESCRIPTOR_OUT], err); - if(gadget_->ep_handles[EP_DESCRIPTOR_OUT] >= 0) - { - status_.out_status = BULK_STATUS_IDLE; - thread_bulk_out_id_ = threads_->thread_new(&async_usb_gadget::thread_read_bulk); - } - } - - return 0; -} -int async_usb_gadget::close_bulk(bool incl_ep0) -{ - dyn_mem_ptr mem = nullptr; - data_source_ptr data = nullptr; - int cnt = 0; - - sent_que_.quit(); - cmd_que_.quit(); - - if (gadget_->ep_handles[EP_DESCRIPTOR_IN] >= 0) - { - cnt = close(gadget_->ep_handles[EP_DESCRIPTOR_IN]); - status_.in_status = BULK_STATUS_NOT_START; - log_cls::log(LOG_LEVEL_ALL, "close BULK-IN endpoint %d = %d\n", gadget_->ep_handles[EP_DESCRIPTOR_IN], cnt); - } - if (gadget_->ep_handles[EP_DESCRIPTOR_OUT] >= 0) - { - cnt = close(gadget_->ep_handles[EP_DESCRIPTOR_OUT]); - status_.out_status = BULK_STATUS_NOT_START; - log_cls::log(LOG_LEVEL_ALL, "close BULK-OUT endpoint %d = %d\n", gadget_->ep_handles[EP_DESCRIPTOR_OUT], cnt); - } - gadget_->ep_handles[EP_DESCRIPTOR_IN] = gadget_->ep_handles[EP_DESCRIPTOR_OUT] = -1; - if (thread_bulk_in_id_ >= 0) - { - sent_que_.quit(); - log_cls::log(LOG_LEVEL_ALL, "Stop BULK-IN thread.\n"); - threads_->thread_stop(thread_bulk_in_id_); - } - if (thread_bulk_out_id_ >= 0) - { - log_cls::log(LOG_LEVEL_ALL, "Stop BULK-OUT thread.\n"); - threads_->thread_stop(thread_bulk_out_id_); - } - thread_bulk_out_id_ = thread_bulk_in_id_ = -1; - - if(incl_ep0) - { - log_cls::log(LOG_LEVEL_ALL, "Close usb device (EP0) %d.\n", gadget_->usb_device); - close(gadget_->usb_device); - gadget_->usb_device = -1; - if(thread_ep0_id_ >= 0) - threads_->thread_stop(thread_ep0_id_); - thread_ep0_id_ = -1; - } - - cnt = 0; - while (cmd_que_.take(mem, false)) - { - mem->release(); - cnt++; - } - status_.task_cnt = 0; - log_cls::log(LOG_LEVEL_ALL, "Clear %d command(s) in command-queue\n", cnt); - - cnt = 0; - while (sent_que_.take(data, false)) - { - data->release(); - cnt++; - } - status_.bytes_to_sent = status_.packets_to_sent = 0; - log_cls::log(LOG_LEVEL_ALL, "Clear %d reply(s) in sent-queue\n", cnt); - - return 0; -} -int async_usb_gadget::handle_ctrl_message(dyn_mem_ptr data) -{ - struct usb_functionfs_event* pev = (struct usb_functionfs_event*)data->ptr(); - dyn_mem_ptr reply = nullptr; - - switch (pev->type) - { - case FUNCTIONFS_ENABLE: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS ENABLE\n"); - if (gadget_->ep_handles[EP_DESCRIPTOR_IN] < 0) - { - open_bulk(); - } - break; - case FUNCTIONFS_DISABLE: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS DISABLE\n"); - close_bulk(); - break; - case FUNCTIONFS_SETUP: - // log_cls::log(LOG_LEVEL_ALL, "%s: control(type-%x, req-%x, ind-%x, val-%x, len-%x)\n", chronograph::now().c_str() - // , pev->u.setup.bRequestType, pev->u.setup.bRequest, pev->u.setup.wIndex, pev->u.setup.wValue, pev->u.setup.wLength); - data->add_ref(); - reply = handle_ctrl_setup(data); - break; - case FUNCTIONFS_BIND: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS BIND\n"); - break; - case FUNCTIONFS_UNBIND: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS UNBIND\n"); - break; - case FUNCTIONFS_SUSPEND: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS SUSPEND\n"); - break; - case FUNCTIONFS_RESUME: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS RESUME\n"); - break; - } - - if (pev->u.setup.bRequestType & USB_DIR_IN) - { - // if host need data back, and reply is null, we send nonsense data back ... - if (!reply) - { - reply = dyn_mem::memory(pev->u.setup.wLength + sizeof(uint16_t)); - reply->set_len(pev->u.setup.wLength); - for (int i = 0; i <= pev->u.setup.wLength / sizeof(uint16_t); ++i) - ((uint16_t*)reply->ptr())[i] = 0x0baad; - } - - int s = write(gadget_->usb_device, reply->ptr(), reply->get_rest()); - reply->release(); - } - - data->release(); - return 0; -} -dyn_mem_ptr async_usb_gadget::handle_ctrl_setup(dyn_mem_ptr data) -{ - struct usb_functionfs_event* pev = (struct usb_functionfs_event*)data->ptr(); - bool handled = (pev->u.setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR; - dyn_mem_ptr reply = nullptr; - uint32_t err = 0; - - if(handled) - { - switch (pev->u.setup.bRequest) - { - case USB_REQ_EP0_GET_PROTO_VER: - reply = dyn_mem::memory(sizeof(short)); - *(short*)reply->ptr() = PROTOCOL_VER; - reply->set_len(sizeof(short)); - break; - case USB_REQ_EP0_GET_STATUS: - reply = dyn_mem::memory(sizeof(struct _ep0_reply)); - { - reply->put((void*)&status_, sizeof(status_)); - } - break; - case USB_REQ_EP0_RESET_BULK: - reply = dyn_mem::memory(sizeof(uint32_t)); - if(!reset_bulk_) - { - log_cls::log(LOG_LEVEL_DEBUG, "Reset bulk ...\n"); - reset_bulk_ = true; - wait_ep0_->trigger(); - } - else - err = EBUSY; - reply->put(&err, sizeof(err)); - break; - default: - handled = false; - } - } - if(!handled && unhandled_ep0_) - { - log_cls::log(LOG_LEVEL_ALL, "EP0 event(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) has not handled by user business.\n" - , pev->u.setup.bRequestType, pev->u.setup.bRequest, pev->u.setup.wValue, pev->u.setup.wIndex, pev->u.setup.wLength); - reply = unhandled_ep0_(pev); - } - - data->release(); - - return reply; -} -int async_usb_gadget::inner_write_bulk(data_source_ptr data, int* err) -{ - unsigned char* ptr = data->ptr(); - size_t bulk_size = gadget_->ep_config[EP_DESCRIPTOR_IN]->ep_desc[0].ep_desc.wMaxPacketSize, - total = data->get_rest(), off = 0, size = total > bulk_size ? bulk_size : total; - int w = 0; - - if(data->is_memory_block()) - { - while(!reset_bulk_ && (w = write(gadget_->ep_handles[EP_DESCRIPTOR_IN], ptr + off, size)) > 0) - { - off += w; - status_.bytes_to_sent -= w; - if(off >= total) - break; - if(off + bulk_size < total) - size = bulk_size; - else - size = total - off; - } - if(w <= 0 && err) - *err = errno; - } - else - { - dyn_mem_ptr buf = dyn_mem::memory(bulk_size); - uint32_t len = bulk_size; - - if(err) - *err = 0; - total = 0; - while(!reset_bulk_ && (w = data->fetch_data(buf->ptr(), &len)) == 0) - { - ptr = buf->ptr(); - off = 0; - w = write(gadget_->ep_handles[EP_DESCRIPTOR_IN], ptr + off, len); - if(w > 0 && w + off == len) - status_.bytes_to_sent -= w; - while(!reset_bulk_ && w > 0 && w + off < len) - { - status_.bytes_to_sent -= w; - total += w; - off += w; - w = write(gadget_->ep_handles[EP_DESCRIPTOR_IN], ptr + off, len - off); - } - - if(w <= 0) - { - if(err) - *err = errno; - break; - } - else - total += w; - - if(data->get_rest() == 0) - break; - len = bulk_size; - } - buf->release(); - off = total; - log_cls::log(LOG_LEVEL_ALL, "Finished in send large content with %u bytes.\n", total); - } - - return off; -} - -void async_usb_gadget::thread_check_ep0_status(void) -{ - uint32_t id = 0, prev_id = 0; - int status = EP0_STATUS_IDLE, prev_s = status; - int data = 0, prev_d = 0; - int cnt = 0; - char buf[40] = { 0 }; - - while (run_) - { - if (wait_ep0_->wait(1000)) - { - if (run_) - { - // only ONE task to do - reset bulk ... - if (thread_restart_id_ != -1) - threads_->thread_stop(thread_restart_id_); - thread_restart_id_ = threads_->thread_new(&async_usb_gadget::thread_restart_bulk); - } - } - else - { - get_ep0_status(&id, &status, &data); - if (id == prev_id) - { - if (prev_s == status && prev_d == data && status != EP0_STATUS_IDLE) - { - cnt++; - if (cnt >= 5) - { - log_cls::log(LOG_LEVEL_ALL, "-xxx- EP0 blocked in status %s !!!\n", ep0_status_desc(status, buf)); - - // do something to resolve this problem here ... - } - } - else - { - prev_s = status; - prev_d = data; - cnt = 0; - } - } - else - { - prev_id = id; - prev_s = status; - prev_d = data; - cnt = 0; - } - } - } -} -void async_usb_gadget::thread_read_ep0(void) -{ - struct timeval timeout; - int headl = sizeof(struct usb_functionfs_event), - datal = 128, // gadget_->usb_config->dev_desc.bMaxPacketSize0, - ret = 0; - dyn_mem_ptr mem = dyn_mem::memory(headl + datal); - uint8_t* ptr = mem->ptr(); - uint32_t recycles = 0; - struct usb_functionfs_event* pe = (struct usb_functionfs_event*)ptr; - - log_cls::log(LOG_LEVEL_ALL, "EP0 monitoring thread(%p of id %lx) started ...\n", &async_usb_gadget::thread_read_ep0, sys_util::thread_id(std::this_thread::get_id())); - while(run_) - { - set_ep0_status(++recycles, EP0_STATUS_IDLE, 0); - - ret = wait_fd_event(gadget_->usb_device); - if( ret <= 0 ) - { - log_cls::log(LOG_LEVEL_ALL, "select EP0(%d) failed: %d(%s)\n", gadget_->usb_device, errno, strerror(errno)); - break; - } - - // timeout.tv_sec = 0; - ret = read(gadget_->usb_device, ptr, headl); - if (ret < 0) - { - log_cls::log(LOG_LEVEL_ALL, "read EP0 failed: %d(%s)\n", errno, strerror(errno)); - break; - } - - bool good = true; - if(pe->u.setup.bRequestType & USB_DIR_IN) - mem->set_len(headl); - else - { - if (pe->u.setup.wLength > datal) - { - good = false; - log_cls::log(LOG_LEVEL_ALL, "EP0 data too long(%d > %d), we will discard this packet(0x%x, 0x%x, 0x%x, 0x%x)!\n", pe->u.setup.wLength, datal, - pe->u.setup.bRequestType, pe->u.setup.bRequest, pe->u.setup.wValue, pe->u.setup.wIndex); - - // we read-out whole data here ... - int rest = pe->u.setup.wLength; - while (rest > 0) - { - set_ep0_status(recycles, EP0_STATUS_READ_INVAL_DATA, rest); - read(gadget_->usb_device, ptr + headl, rest > datal ? datal : rest); - rest -= datal; - } - } - else - { - set_ep0_status(recycles, EP0_STATUS_READ_DATA, pe->u.setup.wLength); - read(gadget_->usb_device, ptr + headl, pe->u.setup.wLength); - mem->set_len(headl + pe->u.setup.wLength); - } - } - if (good) - { - set_ep0_status(recycles, EP0_STATUS_HANDLE_CMD, pe->u.setup.bRequest); - mem->add_ref(); - handle_ctrl_message(mem); - } - } - mem->release(); - log_cls::log(LOG_LEVEL_ALL, "EP0 monitoring thread exited.\n"); -} -void async_usb_gadget::thread_read_bulk(void) -{ - log_cls::log(LOG_LEVEL_ALL, "thread_read_bulk(%p of id %lx) started ...\n", &async_usb_gadget::thread_read_bulk, sys_util::thread_id(std::this_thread::get_id())); - size_t bulk_size = gadget_->ep_config[EP_DESCRIPTOR_OUT]->ep_desc[0].ep_desc.wMaxPacketSize; - uint32_t cnt_0 = 0; - - while(run_) - { - dyn_mem_ptr buf(dyn_mem::memory(bulk_size)); - int l = 0; - - // l = wait_fd_event(gadget_->ep_handles[EP_DESCRIPTOR_OUT]); - // if (l <= 0) - // { - // log_cls::log(LOG_LEVEL_ALL, "wait bulk-out event failed: %d\n", errno); - // break; - // } - - status_.out_status = BULK_STATUS_IO; - l = read(gadget_->ep_handles[EP_DESCRIPTOR_OUT], buf->ptr(), bulk_size); - if(l <= 0) - { - buf->release(); - if(errno) - { - log_cls::log(LOG_LEVEL_ALL, "read bulk failed: %d(%s)\n", errno, strerror(errno)); - status_.out_status = BULK_STATUS_ERROR; - status_.out_err = errno; - break; - } - else - { - cnt_0++; - // log_cls::log(LOG_LEVEL_ALL, "read bulk with 0 byte.\n"); - } - } - else if (reset_bulk_ || !run_) - { - // if(cnt_0) - // { - // log_cls::log(LOG_LEVEL_ALL, "read bulk with 0 byte - %u time(s).\n", cnt_0); - // cnt_0 = 0; - // } - log_cls::log(LOG_LEVEL_ALL, "thread_pump_task do reset-bulk ...\n"); - buf->release(); - if(!run_) - break; - } - else - { - // if(cnt_0) - // { - // log_cls::log(LOG_LEVEL_ALL, "read bulk with 0 byte - %u time(s).\n", cnt_0); - // cnt_0 = 0; - // } - status_.out_status = BULK_STATUS_IDLE; - buf->set_len(l); - cmd_que_.save(buf, true); - } - } - if(status_.out_status == BULK_STATUS_IDLE) - status_.out_status = reset_bulk_ ? BULK_STATUS_RESET : BULK_STATUS_NOT_START; - - log_cls::log(LOG_LEVEL_ALL, "thread_read_bulk exited.\n"); -} -void async_usb_gadget::thread_write_bulk(void) -{ - log_cls::log(LOG_LEVEL_ALL, "thread_write_bulk(%p of id %lx) started ...\n", &async_usb_gadget::thread_write_bulk, sys_util::thread_id(std::this_thread::get_id())); - - status_.in_status = BULK_STATUS_IDLE; - while(run_) - { - data_source_ptr data; - int err = 0; - - if(sent_que_.take(data, true)) - { - if(reset_bulk_) - { - log_cls::log(LOG_LEVEL_ALL, "thread_write_bulk do reset-bulk ...\n"); - data->release(); - continue; - } - - status_.packets_to_sent = sent_que_.size(); - status_.bytes_to_sent = data->get_rest(); - status_.in_status = BULK_STATUS_IO; - inner_write_bulk(data, &err); - status_.in_status = BULK_STATUS_IDLE; - status_.bytes_to_sent = 0; - data->release(); - if(err) - { - log_cls::log(LOG_LEVEL_ALL, "write bulk failed: %d(%s)\n", errno, strerror(errno)); - status_.in_status = BULK_STATUS_ERROR; - status_.in_err = err; - break; - } - } - // if (reset_bulk_) - // break; - } - if(status_.in_status == BULK_STATUS_IDLE) - status_.in_status = reset_bulk_ ? BULK_STATUS_RESET : BULK_STATUS_NOT_START; - - log_cls::log(LOG_LEVEL_ALL, "thread_write_bulk exited.\n"); -} -void async_usb_gadget::thread_pump_task(void) -{ - log_cls::log(LOG_LEVEL_ALL, "thread_pump_task(%p of id %lx) started ...\n", &async_usb_gadget::thread_pump_task, sys_util::thread_id(std::this_thread::get_id())); - - dyn_mem_ptr prev = nullptr, data = nullptr, reply = nullptr; - bool in_err_statu = false; - uint32_t required = 0, used = 0, restore_err_cnt = 0, max_que = 0; - data_holder *dh = nullptr; - LPPACK_BASE pack = nullptr; - uint64_t total_size = 0; - - while(run_) - { - data = nullptr; - if(cmd_que_.take(data, true) && data) - { - status_.task_cnt = cmd_que_.size(); - if(max_que < status_.task_cnt) - max_que = status_.task_cnt; - - if(reset_bulk_) - { - data->release(); - } - else - { - if (in_err_statu) - { - - } - if(prev) - { - log_cls::log(LOG_LEVEL_ALL, "Combine partial packet with length %u and %u ...\n", prev->get_rest(), data->get_rest()); - *prev += *data; - data->release(); - data = prev; - prev = nullptr; - } - - do - { - packet_data_base_ptr pack_data = nullptr; - data_source_ptr ds = nullptr; - - if(dh == nullptr) - { - if (data->get_rest() < sizeof(PACK_BASE)) - break; - else - { - pack = (LPPACK_BASE)data->ptr(); - status_.task_cmd = pack->cmd; - status_.task_pack_id = pack->pack_id; - reply = handle_cmd_(data, &used, &pack_data); - if(pack_data) - { - dh = dynamic_cast(pack_data); - if(!dh) - { - ds = dynamic_cast(pack_data); - if(!ds) - pack_data->release(); - } - else - total_size = 0; - } - } - } - else - { - uint32_t len = data->get_rest(); - int err = 0; // - -#ifndef TEST - err = dh->put_data(data->ptr(), &len); -#endif - if(len < data->get_rest()) - { - log_cls::log(LOG_LEVEL_WARNING, "Put partial data %u/%u! at +%08X with error %d\n", len, data->get_rest(), total_size, err); - } - total_size += len; -#ifdef TEST - { - dyn_mem_ptr back = dyn_mem::memory(data->get_rest()); - back->put(data->ptr(), data->get_rest()); - write_bulk(back); // test -> reply this data back ... - status_.task_required_bytes = dh->get_required() - total_size; - } -#endif - if(dh->is_complete() || err -#ifdef TEST - || total_size >= dh->get_required() -#endif - ) - { - reply = dyn_mem::memory(sizeof(PACK_BASE)); - pack = (LPPACK_BASE)reply->ptr(); - BASE_PACKET_REPLY(*pack, dh->get_packet_command() + 1, dh->get_packet_id(), err); - reply->set_len(sizeof(PACK_BASE)); - - log_cls::log(LOG_LEVEL_ALL, "Finished received file with error(Max queue size is %u): %d, total size = 0x%x\n", max_que, err, total_size); - - dh->release(); - dh = nullptr; - } - used = len; - - if (err) - { - in_err_statu = true; - restore_err_cnt = 0; - } - } - - // first reply the packet ... - if(reply) - { - write_bulk(dynamic_cast(reply)); - reply->release(); - reply = nullptr; - } - - // second send appendix data ... - if (ds) - { - write_bulk(ds); - ds->release(); - ds = nullptr; - } - -#ifndef TEST - status_.task_required_bytes = dh ? dh->get_required() : 0; -#endif - if(status_.task_required_bytes == 0) - status_.task_cmd = status_.task_pack_id = 0; - - data->used(used); - }while(used && data->get_rest()); - - if(data->get_rest()) - prev = data; - else - data->release(); - } - } - if (reset_bulk_) - { - log_cls::log(LOG_LEVEL_ALL, "thread_pump_task do reset-bulk (max command queue size is %u in previous turn) ...\n", max_que); - max_que = 0; - if (prev) - { - prev->release(); - prev = nullptr; - } - if (dh) - { - dh->release(); - dh = nullptr; - } - status_.task_cmd = status_.task_pack_id = status_.task_required_bytes = 0; - } - } - if(prev) - prev->release(); - if (data) - data->release(); - if (reply) - reply->release(); - if (dh) - dh->release(); - - log_cls::log(LOG_LEVEL_ALL, "thread_pump_task exited.\n"); -} -void async_usb_gadget::thread_restart_bulk(void) -{ - dyn_mem_ptr data; - while(cmd_que_.take(data, false)) - data->release(); - - data_source_ptr src; - while(sent_que_.take(src, false)) - src->release(); - - sent_que_.quit(); - cmd_que_.quit(); - - // close_bulk(); - while(status_.in_status != BULK_STATUS_IDLE || status_.out_status != BULK_STATUS_IO || status_.task_cmd) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - - // open_bulk(); - // cmd_que_.quit(); - reset_bulk_ = false; - log_cls::log(LOG_LEVEL_ALL, "reset bulk completed.\n"); -} - -int async_usb_gadget::stop(void) -{ - run_ = false; - close_bulk(true); - threads_->thread_stop(); - - return 0; -} -int async_usb_gadget::write_bulk(data_source_ptr data) -{ - if(!reset_bulk_) - { - data->add_ref(); - sent_que_.save(data, true); - } - - return 0; -} diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/usb_io.h b/device/gxx-linux/testusb/usb-rk3399/src/common/usb_io.h deleted file mode 100644 index 45df339..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/usb_io.h +++ /dev/null @@ -1,118 +0,0 @@ -#pragma once - -// Objects IO -// -// created on 2023-03-10 - -#include "referer.h" -#include "packet.h" -#include "ipc_util.h" -#include "data.h" - -#include -#include -#include -#include -#include "../../inc/usb_gadget.h" - - -// callback proto -// -// parameters: usb_functionfs_event* - the function event ptr -// -// dyn_mem_ptr - the packet buffer, read-only -// -// uint32_t* - to return how many data in bytes the handler consumed -// -// normally, the value should be PACK_BASE::payload_len, i.e. the handler consume all data of an entire packet -// -// when invalid packet, suggest use the entire data -// -// packet_data_base_ptr* - return data_holder or data_source or nullptr -// -// data_holder: the packet/command need more data than dyn_mem_ptr provides to complete the business. such as 'write a large file' -// -// data_source: the reply content may be a large data (a large file content) -// -// return value of all routines is the reply packet, nullptr if the packet need not reply -// -#define FUNCTION_PROTO_UNHANDLED_EP0 dyn_mem_ptr(struct usb_functionfs_event*) - - -typedef union _setup_request_type // subclass of usb_ctrlrequest::bRequestType -{ - uint8_t type8; - struct - { - uint8_t receiver : 5; // 0 - device; 1 - interface; 2 - endpoint; 3 - other; others - reserved - uint8_t category : 2; // 0 - standard; 1 - class; 2 - vendor/user defined; 3 - reserved - uint8_t direction : 1; // 0 - host to device; 1 - device to host - }; -}REQTYPE; - - - -class async_usb_gadget : public refer -{ - thread_pool* threads_ = nullptr; - volatile bool run_ = true; - volatile bool reset_bulk_ = false; - usb_gadget *gadget_ = nullptr; - int thread_ep0_id_ = -1; - int thread_bulk_in_id_ = -1; - int thread_bulk_out_id_ = -1; - int thread_restart_id_ = -1; - volatile EP0REPLYSTATUS status_; - safe_fifo cmd_que_; - safe_fifo sent_que_; - - enum - { - EP0_STATUS_IDLE = 0, - EP0_STATUS_READ_DATA, // ep0_statu::data is rest data len - EP0_STATUS_READ_INVAL_DATA, // ep0_statu::data is rest data len - EP0_STATUS_HANDLE_CMD, - }; - volatile struct _ep0_statu - { - uint32_t id; - int status; - int data; - }ep0_status_; - MUTEX ep0_status_lock_; - linux_event *wait_ep0_; - - std::function unhandled_ep0_; - std::function handle_cmd_; - - const char* ep0_status_desc(int ep0_status, char* unk_buf/*>= 40 bytes*/); - void set_ep0_status(uint32_t id, int status, int data); - void get_ep0_status(uint32_t* id, int* status, int* data); - - int wait_fd_event(int fd, int to_ms = -1); - - int open_bulk(void); - int close_bulk(bool incl_ep0 = false); - int handle_ctrl_message(dyn_mem_ptr data); - dyn_mem_ptr handle_ctrl_setup(dyn_mem_ptr data); // user command ... - int inner_write_bulk(data_source_ptr data, int* err = nullptr); - - void thread_check_ep0_status(void); - void thread_read_ep0(void); - void thread_read_bulk(void); - void thread_write_bulk(void); - void thread_pump_task(void); - void thread_restart_bulk(void); - -public: - async_usb_gadget(usb_gadget* gadget, std::function unhandled_ep0 = std::function() - , std::function cmd_handler = std::function()); - -protected: - ~async_usb_gadget(); - -public: - int stop(void); - int write_bulk(data_source_ptr data); -}; - diff --git a/device/gxx-linux/testusb/usb-rk3399/src/logs_out.cpp b/device/gxx-linux/testusb/usb-rk3399/src/logs_out.cpp deleted file mode 100644 index 363d1ba..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/logs_out.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * CAMTP Responder - * Copyright (c) 2020 Holdtecs Technologies - * - * CAMTP Responder is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * CAMTP Responder is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 3 for more details. - * - * You should have received a copy of the GNU General Public License - * along with CAMTP Responder; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file logs_out.c - * @brief log output functions - * @author *** - */ - -#include "buildconf.h" - -#include -#include -#include - -#include "logs_out.h" - -void timestamp(char * timestr, int maxsize) -{ - time_t ltime; - struct tm * local_time; - - ltime = time(NULL); - timestr[0] = 0; - - local_time = localtime(<ime); - - snprintf(timestr, maxsize, "%.2d:%.2d:%.2d",local_time->tm_hour, local_time->tm_min, local_time->tm_sec ); -} - -#ifdef DEBUG -int is_printable_char(unsigned char c) -{ - int i; - unsigned char specialchar[]={"&#{}()|_@=$!?;+*-"}; - - if( (c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9') ) - { - return 1; - } - - i = 0; - while(specialchar[i]) - { - if(specialchar[i] == c) - { - return 1; - } - - i++; - } - - return 0; -} - -void printbuf(void * buf,int size) -{ - #define PRINTBUF_HEXPERLINE 16 - #define PRINTBUF_MAXLINE_SIZE ((3*PRINTBUF_HEXPERLINE)+1+PRINTBUF_HEXPERLINE+2) - - int i,j; - unsigned char *ptr = (unsigned char*)buf; - char tmp[8]; - char str[PRINTBUF_MAXLINE_SIZE]; - - memset(str, ' ', PRINTBUF_MAXLINE_SIZE); - str[PRINTBUF_MAXLINE_SIZE-1] = 0; - - j = 0; - for(i=0;i -#include "logs_out.h" -#include -#include -#include -#include "usbstring.h" -#include "default_cfg.h" -#include -#include -#include -#include - -#ifdef ASYNC_EP -#include "log_util.h" -#endif - -#define CONFIG_VALUE 1 -#define USB_MAX_PACKAGE_LENGTH_FILE "/opt/usbpkgconfig" - -// extern int errno; -static int get_system_output(const char *cmd) -{ - printf("shell command: %s", cmd); - int ret = 0; - FILE *fp=NULL; - fp = popen(cmd, "r"); - if (fp) - { - char buf[1024] = {0}; - int rv = fread(buf, 1, sizeof(buf) - 1, fp); - printf(" -- (%d)\n", rv); - if(buf[0]) - { - printf(buf); - printf("\n"); - } - pclose(fp); - } - else - { - printf("popen failed\n"); - ret = errno; - } - - return ret; -} - -static struct usb_gadget_strings strings = { - .language = 0x0409, /* en-us */ - .strings = 0, -}; - -typedef struct camtp_device_status_ { - uint16_t wLength; - uint16_t wCode; -}camtp_device_status; - -static std::shared_ptr bulk_sent_; -static std::shared_ptr bulk_read_; -static std::shared_ptr int_sent_; - -const int UsbDevice::cacheSize = 64*1024; - - -int camtp_load_config_file(camtp_ctx * context, const char * conffile) -{ - int err = 0; - FILE * f; - char line[MAX_CFG_STRING_SIZE]; - - memset((void*)&context->usb_cfg,0x00, sizeof(camtp_usb_cfg)); - - // Set default config - strncpy(context->usb_cfg.usb_device_path, USB_DEV, MAX_CFG_STRING_SIZE); - strncpy(context->usb_cfg.usb_endpoint_in, USB_EPIN, MAX_CFG_STRING_SIZE); - strncpy(context->usb_cfg.usb_endpoint_out, USB_EPOUT, MAX_CFG_STRING_SIZE); - strncpy(context->usb_cfg.usb_endpoint_intin, USB_EPINTIN, MAX_CFG_STRING_SIZE); - strncpy(context->usb_cfg.usb_string_manufacturer, MANUFACTURER, MAX_CFG_STRING_SIZE); - strncpy(context->usb_cfg.usb_string_product, PRODUCT, MAX_CFG_STRING_SIZE); - strncpy(context->usb_cfg.usb_string_serial, SERIALNUMBER, MAX_CFG_STRING_SIZE); - strncpy(context->usb_cfg.usb_string_version, "Rev A", MAX_CFG_STRING_SIZE); - strncpy(context->usb_cfg.usb_string_interface, "camtp", MAX_CFG_STRING_SIZE); - - context->usb_cfg.usb_vendor_id = USB_DEV_VENDOR_ID; - context->usb_cfg.usb_product_id = USB_DEV_PRODUCT_ID; - context->usb_cfg.usb_class = USB_DEV_CLASS; - context->usb_cfg.usb_subclass = USB_DEV_SUBCLASS; - context->usb_cfg.usb_protocol = USB_DEV_PROTOCOL; - context->usb_cfg.usb_dev_version = USB_DEV_VERSION; - std::ifstream fs(USB_MAX_PACKAGE_LENGTH_FILE); - int maxpackagesize =0; - fs >> maxpackagesize; - maxpackagesize<=0?maxpackagesize = 512:maxpackagesize; - printf("vid::pid - %04X::%04X\n", context->usb_cfg.usb_vendor_id, context->usb_cfg.usb_product_id); - - //printf("MAX_PACKET_SIZE = %d \n",maxpackagesize); - context->usb_cfg.usb_max_packet_size = maxpackagesize; - //context->usb_cfg.usb_max_packet_size = MAX_PACKET_SIZE; - context->usb_cfg.usb_functionfs_mode = USB_FFS_MODE; - - context->usb_cfg.wait_connection = 0; - context->usb_cfg.loop_on_disconnect = 0; - - context->usb_cfg.show_hidden_files = 1; - - context->usb_cfg.val_umask = -1; - - PRINT_MSG("USB Device path : %s",context->usb_cfg.usb_device_path); - PRINT_MSG("USB In End point path : %s",context->usb_cfg.usb_endpoint_in); - PRINT_MSG("USB Out End point path : %s",context->usb_cfg.usb_endpoint_out); - PRINT_MSG("USB Event End point path : %s",context->usb_cfg.usb_endpoint_intin); - PRINT_MSG("USB Max packet size : 0x%X bytes",context->usb_cfg.usb_max_packet_size); - - PRINT_MSG("Manufacturer string : %s",context->usb_cfg.usb_string_manufacturer); - PRINT_MSG("Product string : %s",context->usb_cfg.usb_string_product); - PRINT_MSG("Serial string : %s",context->usb_cfg.usb_string_serial); - PRINT_MSG("Firmware Version string : %s", context->usb_cfg.usb_string_version); - PRINT_MSG("Interface string : %s",context->usb_cfg.usb_string_interface); - - PRINT_MSG("USB Vendor ID : 0x%.4X",context->usb_cfg.usb_vendor_id); - PRINT_MSG("USB Product ID : 0x%.4X",context->usb_cfg.usb_product_id); - PRINT_MSG("USB class ID : 0x%.2X",context->usb_cfg.usb_class); - PRINT_MSG("USB subclass ID : 0x%.2X",context->usb_cfg.usb_subclass); - PRINT_MSG("USB Protocol ID : 0x%.2X",context->usb_cfg.usb_protocol); - PRINT_MSG("USB Device version : 0x%.4X",context->usb_cfg.usb_dev_version); - - if(context->usb_cfg.usb_functionfs_mode) - { - PRINT_MSG("USB FunctionFS Mode"); - } - else - { - PRINT_MSG("USB GadgetFS Mode"); - } - - PRINT_MSG("Wait for connection : %i",context->usb_cfg.wait_connection); - PRINT_MSG("Loop on disconnect : %i",context->usb_cfg.loop_on_disconnect); - PRINT_MSG("Show hidden files : %i",context->usb_cfg.show_hidden_files); - if(context->usb_cfg.val_umask >= 0) - { - PRINT_MSG("File creation umask : %03o",context->usb_cfg.val_umask); - } - else - { - PRINT_MSG("File creation umask : System default umask"); - } - - return err; -} - -void UsbDevice::fill_if_descriptor(camtp_ctx * ctx, usb_gadget * usbctx, struct usb_interface_descriptor * desc) -{ - memset(desc,0,sizeof(struct usb_interface_descriptor)); - - desc->bLength = sizeof(struct usb_interface_descriptor); - desc->bDescriptorType = USB_DT_INTERFACE; //!< nick - desc->bInterfaceNumber = 0; - desc->iInterface = 1; - desc->bAlternateSetting = 0; - desc->bNumEndpoints = 3; - - desc->bInterfaceClass = ctx->usb_cfg.usb_class; - desc->bInterfaceSubClass = ctx->usb_cfg.usb_subclass; - desc->bInterfaceProtocol = ctx->usb_cfg.usb_protocol; - if( ctx->usb_cfg.usb_functionfs_mode ) - { - desc->iInterface = 1; - } - else - { - desc->iInterface = STRINGID_INTERFACE; - } - - log_cls::log(LOG_LEVEL_ALL, "fill_if_descriptor:\n"); - PRINT_DEBUG_BUF(desc, sizeof(struct usb_interface_descriptor)); - - return; -} - -void UsbDevice::fill_ep_descriptor(camtp_ctx * ctx, usb_gadget * usbctx,struct usb_endpoint_descriptor_no_audio * desc,int index,unsigned int flags) -{ - memset(desc,0,sizeof(struct usb_endpoint_descriptor_no_audio)); - - desc->bLength = USB_DT_ENDPOINT_SIZE; - desc->bDescriptorType = USB_DT_ENDPOINT; - - if(flags & EP_OUT_DIR) - desc->bEndpointAddress = USB_DIR_OUT | (index); - else - desc->bEndpointAddress = USB_DIR_IN | (index); - - if(flags & EP_BULK_MODE) - { - desc->bmAttributes = USB_ENDPOINT_XFER_BULK; - desc->wMaxPacketSize = ctx->usb_cfg.usb_max_packet_size; - //printf("desc->wMaxPacketSize = %d \n",desc->wMaxPacketSize); - } - else - { - desc->bmAttributes = USB_ENDPOINT_XFER_INT; - desc->wMaxPacketSize = 64; // HS size 64 - desc->bInterval = 6; - } - -#if defined(CONFIG_USB_SS_SUPPORT) - if(flags & EP_SS_MODE) - { - ep_cfg_descriptor * ss_descriptor; - - ss_descriptor = (ep_cfg_descriptor *)desc; - - ss_descriptor->ep_desc_comp.bLength = sizeof(struct usb_ss_ep_comp_descriptor); - ss_descriptor->ep_desc_comp.bDescriptorType = USB_DT_SS_ENDPOINT_COMP; - if(flags & EP_BULK_MODE){ - ss_descriptor->ep_desc_comp.bMaxBurst = 15; - ss_descriptor->ep_desc_comp.wBytesPerInterval = 0x00; - }else{ - ss_descriptor->ep_desc_comp.bMaxBurst = 0; - ss_descriptor->ep_desc_comp.wBytesPerInterval = 64;//0x1c - } - } -#endif - - log_cls::log(LOG_LEVEL_ALL, "fill_ep_descriptor:\n"); - PRINT_DEBUG_BUF(desc, sizeof(struct usb_endpoint_descriptor_no_audio)); - - return; -} - -int UsbDevice::add_usb_string(usb_gadget * usbctx, int id, char * string) -{ - int i; - - i = 0; - - while( i < MAX_USB_STRING ) - { - if( !usbctx->stringtab[i].id ) - { - usbctx->stringtab[i].id = id; - if(string) - { - usbctx->stringtab[i].str = (char*)malloc(strlen(string) + 1); - if(usbctx->stringtab[i].str) - { - memset(usbctx->stringtab[i].str,0,strlen(string) + 1); - strcpy(usbctx->stringtab[i].str,string); - return i; - } - else - { - usbctx->stringtab[i].id = 0; - return -2; - } - } - else - { - return i; - } - } - i++; - } - - return -1; -} - -void UsbDevice::fill_config_descriptor(camtp_ctx * ctx , usb_gadget * usbctx,struct usb_config_descriptor * desc,int total_size, int hs) -{ - memset(desc,0,sizeof(struct usb_config_descriptor)); - - desc->bLength = sizeof(struct usb_config_descriptor); - desc->bDescriptorType = USB_DT_CONFIG; - desc->wTotalLength = desc->bLength + total_size; - desc->bNumInterfaces = 1; - desc->bConfigurationValue = CONFIG_VALUE; - if(hs) - desc->iConfiguration = STRINGID_CONFIG_HS; - else - desc->iConfiguration = STRINGID_CONFIG_LS; - desc->bmAttributes = USB_CONFIG_ATT_ONE; - desc->bMaxPower = 1; - - log_cls::log(LOG_LEVEL_ALL, "fill_config_descriptor: (Total Len : %u + %d = %d)\n", (unsigned int) sizeof(struct usb_config_descriptor), total_size, desc->wTotalLength); - PRINT_DEBUG_BUF(desc, sizeof(struct usb_config_descriptor)); - - return; -} - -void UsbDevice::fill_dev_descriptor(camtp_ctx * ctx, usb_gadget * usbctx,struct usb_device_descriptor * desc) -{ - memset(desc,0,sizeof(struct usb_device_descriptor)); - - desc->bLength = USB_DT_DEVICE_SIZE; - desc->bDescriptorType = USB_DT_DEVICE; - desc->bDeviceClass = ctx->usb_cfg.usb_class; - desc->bDeviceSubClass = ctx->usb_cfg.usb_subclass; - desc->bDeviceProtocol = ctx->usb_cfg.usb_protocol; - desc->idVendor = ctx->usb_cfg.usb_vendor_id; - desc->idProduct = ctx->usb_cfg.usb_product_id; - desc->bcdDevice = ctx->usb_cfg.usb_dev_version; // Version - // Strings - desc->iManufacturer = STRINGID_MANUFACTURER; - desc->iProduct = STRINGID_PRODUCT; - desc->iSerialNumber = STRINGID_SERIAL; - desc->bNumConfigurations = 1; // Only one configuration - - log_cls::log(LOG_LEVEL_ALL, "fill_dev_descriptor:\n"); - PRINT_DEBUG_BUF(desc, sizeof(struct usb_device_descriptor)); - - return; -} - -UsbDevice::UsbDevice(std::function handler, std::function call_back) -: b_connected(false) -, connect_call(call_back) -, usb_(nullptr) -{ - camtp_context.reset(new camtp_ctx); - memset(camtp_context.get(), 0, sizeof(camtp_ctx)); -#ifdef ASYNC_EP - log_cls::initialize(nullptr); - auto bulk_handle = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* required) -> dyn_mem_ptr - { - LPPACK_BASE pack = (LPPACK_BASE)data->ptr(); - uint32_t consume = 0, want = 0; - - if(!used) - used = &consume; - *used = data->get_rest(); - - return handle_bulk_cmd(pack, used, required); - }; - - auto ctrl_unhandle = [&](struct usb_functionfs_event* pev) -> dyn_mem_ptr - { - return unhandled_ep0(pev); - }; - - thread_pool *t = new thread_pool(this); - t->thread_new(&UsbDevice::do_system_command, R"(echo linaro | sudo -S sh -c "echo fe900000.dwc3 > /opt/cfg/usb_gadget/g1/UDC")"); - camtp_load_config_file(camtp_context.get(), ""); - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - usb_ctx = init_usb_camtp_gadget(camtp_context.get()); - if(usb_ctx && usb_ctx->usb_device >= 0) - { - get_system_output(R"(echo linaro | sudo -S sh -c "chmod 777 /dev/ffs-camtp -R")"); - init_eps(usb_ctx, camtp_context->usb_cfg.usb_functionfs_mode, false); - - usb_ = new async_usb_gadget(usb_ctx, ctrl_unhandle, bulk_handle); - } - t->thread_stop(); - t->release(); -#else - thread_main = std::move(std::thread(&UsbDevice::usb_main, this)); - get_system_output(R"(echo linaro | sudo -S sh -c "echo fe900000.dwc3 > /opt/cfg/usb_gadget/g1/UDC")"); -#endif - - //get_system_output(R"(echo linaro | sudo -S sh -c "echo ff580000.usb > /opt/cfg/usb_gadget/g1/UDC")"); - ctrl_handler = handler; - -} - -UsbDevice::~UsbDevice() -{ - pthread_cancel(thread_main.native_handle()); - if(usb_) - { - usb_->stop(); - usb_->release(); - } -} - -int UsbDevice::read_bulk(void *data, int size, int* err, bool full) -{ - int rcv = read(usb_ctx->ep_handles[EP_DESCRIPTOR_OUT], data, size, err, full); - - printf("read_bulk = %d\n", rcv); - - return rcv; -} - -int UsbDevice::write_bulk(void *data, int size, int* err) -{ - return write(usb_ctx->ep_handles[EP_DESCRIPTOR_IN], data, size, err); -} - -int UsbDevice::write_int(void *data, int size, int* err) -{ - return write(usb_ctx->ep_handles[EP_DESCRIPTOR_INT_IN], data, (unsigned char)size, err); -} - -int UsbDevice::write(int fd, void* data, size_t size, int* err) -{ - int writed = 0; - int writing = 0; - uint8_t* src = (uint8_t*)data; - do - { - writing = std::max(0, std::min(cacheSize, (int)(size - writed))); - writing = ::write(fd, src + writed, writing); - if(writing >= 0) - writed += writing; - else - { - printf("wrote(%d, %d) = %d(%s)\n", fd, size, errno, strerror(errno)); - if(err) - *err = errno; - break; - } - }while (writed != size); - - return writed; -} - -int UsbDevice::read(int fd, void* data, size_t size, int* err, bool full) -{ - int readed= 0; - int reading = 0; - uint8_t* buf = (uint8_t*)data; - do - { - reading = std::max(0, std::min(cacheSize, (int)(size - readed))); - reading = ::read(fd, buf + readed, reading); - if(reading > 0) - readed += reading; - else - { - if(err) - *err = errno; - printf("read error(%d): %s\n", errno, strerror(errno)); - break; - } - - }while (readed != size && full); - - return readed; -} - - void UsbDevice::abort_int() - { - ioctl(usb_ctx->ep_handles[EP_DESCRIPTOR_INT_IN], GADGETFS_FIFO_FLUSH); - } - -usb_gadget* UsbDevice::init_usb_camtp_gadget(camtp_ctx * ctx) -{ - usb_gadget * usbctx; - int cfg_size; - int ret,i; - ffs_strings ffs_str; - - usbctx = NULL; - - usbctx = (usb_gadget *)malloc(sizeof(usb_gadget)); - if(usbctx) - { - - memset(usbctx,0,sizeof(usb_gadget)); - - usbctx->usb_device = -1; - usbctx->thread_not_started = 1; - - i = 0; - while( i < EP_NB_OF_DESCRIPTORS ) - { - usbctx->ep_handles[i] = -1; - i++; - } - - add_usb_string(usbctx, STRINGID_MANUFACTURER, ctx->usb_cfg.usb_string_manufacturer); - add_usb_string(usbctx, STRINGID_PRODUCT, ctx->usb_cfg.usb_string_product); - add_usb_string(usbctx, STRINGID_SERIAL, ctx->usb_cfg.usb_string_serial); - add_usb_string(usbctx, STRINGID_CONFIG_HS, (char*)"High speed configuration"); - add_usb_string(usbctx, STRINGID_CONFIG_LS, (char*)"Low speed configuration"); - add_usb_string(usbctx, STRINGID_INTERFACE, ctx->usb_cfg.usb_string_interface); - add_usb_string(usbctx, STRINGID_MAX, NULL); - - strings.strings = usbctx->stringtab; - - usbctx->wait_connection = ctx->usb_cfg.wait_connection; - - for(i=0;i<3;i++) - { - usbctx->ep_config[i] = (ep_cfg*)malloc(sizeof(ep_cfg)); - if(!usbctx->ep_config[i]) - goto init_error; - - memset(usbctx->ep_config[i],0,sizeof(ep_cfg)); - } - - usbctx->ep_path[0] = ctx->usb_cfg.usb_endpoint_in; - usbctx->ep_path[1] = ctx->usb_cfg.usb_endpoint_out; - usbctx->ep_path[2] = ctx->usb_cfg.usb_endpoint_intin; - - usbctx->usb_device = open(ctx->usb_cfg.usb_device_path, O_RDWR|O_SYNC); - log_cls::log(LOG_LEVEL_ALL, "USB device: open(%s) = %d (%d)\n", ctx->usb_cfg.usb_device_path, usbctx->usb_device, usbctx->usb_device == -1 ? errno : 0); - // std::this_thread::sleep_for(std::chrono::milliseconds(15000)); - // printf("USB device: go on ^_^\n"); - - if (usbctx->usb_device <= 0) - { - PRINT_ERROR("init_usb_camtp_gadget : Unable to open %s (%m)", ctx->usb_cfg.usb_device_path); - goto init_error; - } - - cfg_size = sizeof(struct usb_interface_descriptor) + (sizeof(struct usb_endpoint_descriptor_no_audio) * 3); - - if( ctx->usb_cfg.usb_functionfs_mode ) - { - // FunctionFS mode - - usbctx->usb_ffs_config = (usb_ffs_cfg *)malloc(sizeof(usb_ffs_cfg)); - if(!usbctx->usb_ffs_config) - goto init_error; - - memset(usbctx->usb_ffs_config,0,sizeof(usb_ffs_cfg)); - -#ifdef OLD_FUNCTIONFS_DESCRIPTORS // Kernel < v3.15 - usbctx->usb_ffs_config->magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC); -#else - usbctx->usb_ffs_config->magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2); - usbctx->usb_ffs_config->flags = htole32(0); - usbctx->usb_ffs_config->flags |= htole32(FUNCTIONFS_ALL_CTRL_RECIP); - -#ifdef CONFIG_USB_FS_SUPPORT - usbctx->usb_ffs_config->flags |= htole32(FUNCTIONFS_HAS_FS_DESC); -#endif - -#ifdef CONFIG_USB_HS_SUPPORT - usbctx->usb_ffs_config->flags |= htole32(FUNCTIONFS_HAS_HS_DESC); -#endif - -#ifdef CONFIG_USB_SS_SUPPORT - usbctx->usb_ffs_config->flags |= htole32(FUNCTIONFS_HAS_SS_DESC); -#endif - -#endif - usbctx->usb_ffs_config->length = htole32(sizeof(usb_ffs_cfg)); - -#ifdef CONFIG_USB_FS_SUPPORT - usbctx->usb_ffs_config->fs_count = htole32(1 + 3); - - fill_if_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_fs.if_desc); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_fs.ep_desc_in,1, EP_BULK_MODE | EP_IN_DIR); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_fs.ep_desc_out,2, EP_BULK_MODE | EP_OUT_DIR); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_fs.ep_desc_int_in,3, EP_INT_MODE | EP_IN_DIR); -#endif - -#ifdef CONFIG_USB_HS_SUPPORT - usbctx->usb_ffs_config->hs_count = htole32(1 + 3); - fill_if_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_hs.if_desc); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_hs.ep_desc_in,1, EP_BULK_MODE | EP_IN_DIR | EP_HS_MODE); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_hs.ep_desc_out,2, EP_BULK_MODE | EP_OUT_DIR | EP_HS_MODE); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_hs.ep_desc_int_in,3, EP_INT_MODE | EP_IN_DIR | EP_HS_MODE); -#endif - -#ifdef CONFIG_USB_SS_SUPPORT - usbctx->usb_ffs_config->ss_count = htole32(1 + (3*2)); - fill_if_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_ss.if_desc); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_ss.ep_desc_in,1, EP_BULK_MODE | EP_IN_DIR | EP_SS_MODE); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_ss.ep_desc_out,2, EP_BULK_MODE | EP_OUT_DIR | EP_SS_MODE); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_ffs_config->ep_desc_ss.ep_desc_int_in,3, EP_INT_MODE | EP_IN_DIR | EP_SS_MODE); -#endif - - log_cls::log(LOG_LEVEL_ALL, "init_usb_camtp_gadget :\n"); - PRINT_DEBUG_BUF(usbctx->usb_ffs_config, sizeof(usb_ffs_cfg)); - - ret = write(usbctx->usb_device, usbctx->usb_ffs_config, sizeof(usb_ffs_cfg)); - - if(ret != sizeof(usb_ffs_cfg)) - { - PRINT_ERROR("FunctionFS USB Config write error (%d != %zu)",ret,sizeof(usb_ffs_cfg)); - goto init_error; - } - - memset( &ffs_str, 0, sizeof(ffs_strings)); - ffs_str.header.magic = htole32(FUNCTIONFS_STRINGS_MAGIC); - ffs_str.header.length = htole32(sizeof(struct usb_functionfs_strings_head) + sizeof(uint16_t) + strlen(ctx->usb_cfg.usb_string_interface) + 1); - ffs_str.header.str_count = htole32(1); - ffs_str.header.lang_count = htole32(1); - ffs_str.code = htole16(0x0409); // en-us - strcpy(ffs_str.string_data,ctx->usb_cfg.usb_string_interface); - - log_cls::log(LOG_LEVEL_ALL, "write string :\n"); - PRINT_DEBUG_BUF(&ffs_str, sizeof(ffs_strings)); - - ret = write(usbctx->usb_device, &ffs_str, ffs_str.header.length); - - if( ret != ffs_str.header.length ) - { - PRINT_ERROR("FunctionFS String Config write error (%d != %zu)",ret,(size_t)ffs_str.header.length); - goto init_error; - } - } - else - { - usbctx->usb_config = (usb_cfg *)malloc(sizeof(usb_cfg)); - if(!usbctx->usb_config) - goto init_error; - - memset(usbctx->usb_config,0,sizeof(usb_cfg)); - - usbctx->usb_config->head = 0x00000000; - -#ifdef CONFIG_USB_FS_SUPPORT - fill_config_descriptor(ctx, usbctx, &usbctx->usb_config->cfg_fs, cfg_size, 0); - fill_if_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_fs.if_desc); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_fs.ep_desc_in,1, EP_BULK_MODE | EP_IN_DIR); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_fs.ep_desc_out,2, EP_BULK_MODE | EP_OUT_DIR); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_fs.ep_desc_int_in,3, EP_INT_MODE | EP_IN_DIR); -#endif - -#ifdef CONFIG_USB_HS_SUPPORT - fill_config_descriptor(ctx, usbctx, &usbctx->usb_config->cfg_hs, cfg_size, 1); - fill_if_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_hs.if_desc); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_hs.ep_desc_in,1, EP_BULK_MODE | EP_IN_DIR | EP_HS_MODE); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_hs.ep_desc_out,2, EP_BULK_MODE | EP_OUT_DIR | EP_HS_MODE); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_hs.ep_desc_int_in,3, EP_INT_MODE | EP_IN_DIR | EP_HS_MODE); -#endif - -#ifdef CONFIG_USB_SS_SUPPORT - fill_config_descriptor(ctx, usbctx, &usbctx->usb_config->cfg_ss, cfg_size, 1); - fill_if_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_ss.if_desc); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_ss.ep_desc_in,1, EP_BULK_MODE | EP_IN_DIR | EP_SS_MODE); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_ss.ep_desc_out,2, EP_BULK_MODE | EP_OUT_DIR | EP_SS_MODE); - fill_ep_descriptor(ctx, usbctx, &usbctx->usb_config->ep_desc_ss.ep_desc_int_in,3, EP_INT_MODE | EP_IN_DIR | EP_SS_MODE); -#endif - - fill_dev_descriptor(ctx, usbctx,&usbctx->usb_config->dev_desc); - - log_cls::log(LOG_LEVEL_ALL, "init_usb_camtp_gadget :\n"); - PRINT_DEBUG_BUF(usbctx->usb_config, sizeof(usb_cfg)); - - ret = write(usbctx->usb_device, usbctx->usb_config, sizeof(usb_cfg)); - - if(ret != sizeof(usb_cfg)) - { - PRINT_ERROR("GadgetFS USB Config write error (%d != %zu)",ret,sizeof(usb_cfg)); - goto init_error; - } - } - - log_cls::log(LOG_LEVEL_ALL, "init_usb_camtp_gadget : USB config done\n"); - printf("init usb ok!\n"); - - return usbctx; - } - -init_error: - PRINT_ERROR("init_usb_camtp_gadget init error !"); - - deinit_usb_camtp_gadget(usbctx); - - return 0; -} - -void UsbDevice::deinit_usb_camtp_gadget(usb_gadget * usbctx) -{ - int i; - - log_cls::log(LOG_LEVEL_ALL, "entering deinit_usb_camtp_gadget\n"); - - if( usbctx ) - { - usbctx->stop = 1; - - i = 0; - while( i < EP_NB_OF_DESCRIPTORS ) - { - - if( usbctx->ep_handles[i] >= 0 ) - { - log_cls::log(LOG_LEVEL_ALL, "Closing End Point %d...\n",i); - close(usbctx->ep_handles[i] ); - } - i++; - } - - if (usbctx->usb_device >= 0) - { - log_cls::log(LOG_LEVEL_ALL, "Closing usb device...\n"); - printf("close USB device(%d)\n", usbctx->usb_device); - close(usbctx->usb_device); - usbctx->usb_device = - 1; - } - - if( !usbctx->thread_not_started ) - { - log_cls::log(LOG_LEVEL_ALL, "Stopping USB Thread...\n"); - pthread_cancel (usbctx->thread); - pthread_join(usbctx->thread, NULL); - usbctx->thread_not_started = 1; - } - - if(usbctx->usb_config) - { - free(usbctx->usb_config); - usbctx->usb_config = 0; - } - - if(usbctx->usb_ffs_config) - { - free(usbctx->usb_ffs_config); - usbctx->usb_ffs_config = 0; - } - - for(i=0;i<3;i++) - { - if( usbctx->ep_config[i] ) - free( usbctx->ep_config[i] ); - } - - i = 0; - while( i < MAX_USB_STRING ) - { - if( usbctx->stringtab[i].str ) - { - free ( usbctx->stringtab[i].str ); - } - i++; - } - - free( usbctx ); - } - - log_cls::log(LOG_LEVEL_ALL, "leaving deinit_usb_camtp_gadget\n"); -} - -void UsbDevice::usb_main() -{ - int retcode = 0; - int loop_continue = 0; - camtp_load_config_file(camtp_context.get(), ""); - - loop_continue = camtp_context->usb_cfg.loop_on_disconnect; - - do - { - usb_ctx = init_usb_camtp_gadget(camtp_context.get()); - get_system_output(R"(echo linaro | sudo -S sh -c "chmod 777 /dev/ffs-camtp -R")"); - - if (usb_ctx) - { - //camtp_set_usb_handle(camtp_context.get(), usb_ctx, camtp_context->usb_cfg.usb_max_packet_size); - camtp_context->usb_ctx = usb_ctx; - printf("function mode: %d\n", camtp_context->usb_cfg.usb_functionfs_mode); - if (camtp_context->usb_cfg.usb_functionfs_mode) - { - log_cls::log(LOG_LEVEL_ALL, "CAMTP Responder : FunctionFS Mode - entering handle_ffs_ep0\n"); - handle_ffs_ep0(usb_ctx); - } - else - { - log_cls::log(LOG_LEVEL_ALL, "CAMTP Responder : GadgetFS Mode - entering handle_ep0\n"); - handle_ep0(usb_ctx); - } - deinit_usb_camtp_gadget(usb_ctx); - } - else - { - PRINT_ERROR("USB Init failed !\n"); - retcode = -2; - loop_continue = 0; - } - - PRINT_MSG("CAMTP Responder : Disconnected"); - - } while (loop_continue); -} - - -// Function FS mode handler -int UsbDevice::handle_ffs_ep0(usb_gadget * ctx) -{ - struct timeval timeout; - int ret, nevents, i; - fd_set read_set; - struct usb_functionfs_event event; - int status; - - log_cls::log(LOG_LEVEL_ALL, "handle_ffs_ep0 : Entering...\n"); - timeout.tv_sec = 40; - timeout.tv_usec = 0; - - // status = init_eps(ctx,1); - while (!ctx->stop) - { - FD_ZERO(&read_set); - FD_SET(ctx->usb_device, &read_set); - - printf("select EP0 event ...\n"); - if(timeout.tv_sec) - { - ret = select(ctx->usb_device+1, &read_set, NULL, NULL, &timeout); - } - else - { - log_cls::log(LOG_LEVEL_ALL, "Select without timeout\n"); - ret = select(ctx->usb_device+1, &read_set, NULL, NULL, NULL); - } - - if(ctx->wait_connection && ret == 0 ) - continue; - - if( ret <= 0 ) - return ret; - - timeout.tv_sec = 0; - - ret = read(ctx->usb_device, &event, sizeof(event)); - if (ret < 0) - { - PRINT_ERROR("handle_ffs_ep0 : Read error %d (%m)", ret); - goto end; - } - - nevents = ret / sizeof(event); - - log_cls::log(LOG_LEVEL_ALL, "%d event(s)\n", nevents); - - printf("event type = %d\n", event.type); - for (i=0; iep_handles[EP_DESCRIPTOR_IN] <= 0) - { - status = init_eps(ctx,1); - } - else - status = 0; - - break; - case FUNCTIONFS_DISABLE: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS DISABLE\n"); - b_connected = false; - //printf(" USB DISCONNECTED\n"); - if(connect_call) - connect_call(b_connected); - //!< nick usb off - // Set timeout for a reconnection during the enumeration... - timeout.tv_sec = 0; - timeout.tv_usec = 0; - - // Stop the main rx thread. - ctx->stop = 1; - if( !ctx->thread_not_started ) - { - pthread_join(ctx->thread, NULL); - ctx->thread_not_started = 1; - } - - for(int i = 0; i < sizeof(ctx->ep_handles) / sizeof(ctx->ep_handles[0]); ++i) - { - if(ctx->ep_handles[i] > 0) - close(ctx->ep_handles[i]); - ctx->ep_handles[i] = -1; - } -#ifdef EP_AUTO_SEND - if(bulk_sent_.get() && bulk_sent_->joinable()) - bulk_sent_->join(); - bulk_sent_.reset(); - if(bulk_read_.get() && bulk_read_->joinable()) - bulk_read_->join(); - bulk_read_.reset(); - if(int_sent_.get() && int_sent_->joinable()) - int_sent_->join(); - int_sent_.reset(); -#endif - - // But don't close the endpoints ! - ctx->stop = 0; - - break; - case FUNCTIONFS_SETUP: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS SETUP\n"); - handle_setup_request(ctx, &event.u.setup); - break; - case FUNCTIONFS_BIND: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS BIND\n"); - break; - case FUNCTIONFS_UNBIND: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS UNBIND\n"); - break; - case FUNCTIONFS_SUSPEND: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS SUSPEND\n"); - break; - case FUNCTIONFS_RESUME: - log_cls::log(LOG_LEVEL_ALL, "EP0 FFS RESUME\n"); - break; - } - } - } - - ctx->stop = 1; - -end: - log_cls::log(LOG_LEVEL_ALL, "handle_ffs_ep0 : Leaving... (ctx->stop=%d)\n",ctx->stop); - return 1; -} - - -// GadgetFS mode handler -int UsbDevice::handle_ep0(usb_gadget * ctx) -{ - struct timeval timeout; - int ret, nevents, i, cnt; - fd_set read_set; - struct usb_gadgetfs_event events[5]; - - log_cls::log(LOG_LEVEL_ALL, "handle_ep0 : Entering...\n"); - timeout.tv_sec = 4; - timeout.tv_usec = 0; - - while (!ctx->stop) - { - FD_ZERO(&read_set); - FD_SET(ctx->usb_device, &read_set); - - if(timeout.tv_sec) - { - ret = select(ctx->usb_device+1, &read_set, NULL, NULL, &timeout); - } - else - { - log_cls::log(LOG_LEVEL_ALL, "handle_ep0 : Select without timeout\n"); - ret = select(ctx->usb_device+1, &read_set, NULL, NULL, NULL); - } - - if(ctx->wait_connection && ret == 0 ) - continue; - - if( ret <= 0 ) - return ret; - - timeout.tv_sec = 0; - - ret = read(ctx->usb_device, &events, sizeof(events)); - - if (ret < 0) - { - PRINT_ERROR("handle_ep0 : Read error %d (%m)", errno); - goto end; - } - - nevents = ret / sizeof(events[0]); - - log_cls::log(LOG_LEVEL_ALL, "handle_ep0 : %d event(s)\n", nevents); - - for (i=0; istop = 1; - if( !ctx->thread_not_started ) - { - pthread_cancel(ctx->thread); - pthread_join(ctx->thread, NULL); - ctx->thread_not_started = 1; - } - break; - - case GADGETFS_SETUP: - log_cls::log(LOG_LEVEL_ALL, "handle_ep0 : EP0 SETUP event\n"); - handle_setup_request(ctx, &events[i].u.setup); - break; - - case GADGETFS_NOP: - log_cls::log(LOG_LEVEL_ALL, "handle_ep0 : EP0 NOP event\n"); - break; - - case GADGETFS_SUSPEND: - log_cls::log(LOG_LEVEL_ALL, "handle_ep0 : EP0 SUSPEND event\n"); - - break; - - default: - log_cls::log(LOG_LEVEL_ALL, "handle_ep0 : EP0 unknown event : %d\n",events[i].type); - break; - } - } - } - - ctx->stop = 1; - -end: - log_cls::log(LOG_LEVEL_ALL, "handle_ep0 : Leaving (ctx->stop=%d)...\n",ctx->stop); - - return 1; -} - - -void UsbDevice::handle_setup_request(usb_gadget * ctx, struct usb_ctrlrequest* setup) -{ - int status,cnt; - uint8_t buffer[512]; - camtp_device_status dstatus; - - log_cls::log(LOG_LEVEL_ALL, "Setup request 0x%02X\n", setup->bRequest); - - printf("Request: %02X\n", setup->bRequest); - if(ctrl_handler && ctrl_handler(ctx->usb_device, setup, buffer)) - return; - - printf("service not handle: %x\n", setup->bRequest); - switch (setup->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if (setup->bRequestType != USB_DIR_IN) - goto stall; - - switch (setup->wValue >> 8) - { - case USB_DT_STRING: - log_cls::log(LOG_LEVEL_ALL, "Get string id #%d (max length %d)\n", setup->wValue & 0xff, - setup->wLength); - status = usb_gadget_get_string (&strings, setup->wValue & 0xff, buffer); - // Error - if (status < 0) - { - PRINT_ERROR("handle_setup_request : String id #%d (max length %d) not found !\n",setup->wValue & 0xff, setup->wLength); - break; - } - else - { - log_cls::log(LOG_LEVEL_ALL, "Found %d bytes\n", status); - PRINT_DEBUG_BUF(buffer, status); - } - - if ( write (ctx->usb_device, buffer, status) < 0 ) - { - PRINT_ERROR("handle_setup_request - USB_REQ_GET_DESCRIPTOR : usb device write error !"); - break; - } - - return; - break; - default: - log_cls::log(LOG_LEVEL_ALL, "Cannot return descriptor %d\n", (setup->wValue >> 8)); - break; - } - break; - - case USB_REQ_SET_CONFIGURATION: - if (setup->bRequestType != USB_DIR_OUT) - { - log_cls::log(LOG_LEVEL_ALL, "Bad dir\n"); - goto stall; - } - - switch (setup->wValue) - { - case CONFIG_VALUE: - log_cls::log(LOG_LEVEL_ALL, "Set config value\n"); - - if (ctx->ep_handles[EP_DESCRIPTOR_IN] <= 0) - { - status = init_eps(ctx,0); - } - else - status = 0; - - break; - case 0: - log_cls::log(LOG_LEVEL_ALL, "Disable threads\n"); - ctx->stop = 1; - break; - - default: - log_cls::log(LOG_LEVEL_ALL, "Unhandled configuration value %d\n", setup->wValue); - break; - } - - // Just ACK - status = read (ctx->usb_device, &status, 0); - return; - break; - - case USB_REQ_GET_INTERFACE: - log_cls::log(LOG_LEVEL_ALL, "GET_INTERFACE\n"); - buffer[0] = 0; - - if ( write (ctx->usb_device, buffer, 1) < 0 ) - { - PRINT_ERROR("handle_setup_request - USB_REQ_GET_INTERFACE : usb device write error !\n"); - break; - } - - return; - break; - - case USB_REQ_SET_INTERFACE: - log_cls::log(LOG_LEVEL_ALL, "SET_INTERFACE\n"); - ioctl (ctx->ep_handles[EP_DESCRIPTOR_IN], GADGETFS_CLEAR_HALT); - ioctl (ctx->ep_handles[EP_DESCRIPTOR_OUT], GADGETFS_CLEAR_HALT); - ioctl (ctx->ep_handles[EP_DESCRIPTOR_INT_IN], GADGETFS_CLEAR_HALT); - // ACK - status = read (ctx->usb_device, &status, 0); - return; - break; - - } - -stall: - log_cls::log(LOG_LEVEL_ALL, "Stalled\n"); - // Error - if (setup->bRequestType & USB_DIR_IN) - { - if ( read (ctx->usb_device, &status, 0) < 0 ) - { - log_cls::log(LOG_LEVEL_ALL, "handle_setup_request - stall : usb device read error !\n"); - } - } - else - { - if ( write (ctx->usb_device, &status, 0) < 0 ) - { - log_cls::log(LOG_LEVEL_ALL, "handle_setup_request - stall : usb device write error !\n"); - } - } -} - -int UsbDevice::init_ep(usb_gadget * ctx,int index,int ffs_mode, bool open_ep) -{ - int fd,ret; - void * descriptor_ptr; - int descriptor_size; - - log_cls::log(LOG_LEVEL_ALL, "Init end point %s (%d)\n",ctx->ep_path[index],index); - if(open_ep) - { - fd = open(ctx->ep_path[index], O_RDWR); - log_cls::log(LOG_LEVEL_ALL, "open_usb_ep(%s) = %d\n", ctx->ep_path[index], fd); - if ( fd <= 0 ) - { - PRINT_ERROR("init_ep : Endpoint %s (%d) init failed ! : Can't open the endpoint ! (error %d - %m)",ctx->ep_path[index],index,fd); - goto init_ep_error; - } - - ctx->ep_handles[index] = fd; - } - - ctx->ep_config[index]->head = 1; - - descriptor_size = 0; - - if( ctx->usb_ffs_config ) - { -#if defined(CONFIG_USB_SS_SUPPORT) - descriptor_ptr = (void *)&ctx->usb_ffs_config->ep_desc_ss; - descriptor_size = sizeof(ep_cfg_descriptor); -#elif defined(CONFIG_USB_HS_SUPPORT) - descriptor_ptr = (void *)&ctx->usb_ffs_config->ep_desc_hs; - descriptor_size = sizeof(struct usb_endpoint_descriptor_no_audio); -#elif defined(CONFIG_USB_FS_SUPPORT) - descriptor_ptr = (void *)&ctx->usb_ffs_config->ep_desc_fs; - descriptor_size = sizeof(struct usb_endpoint_descriptor_no_audio); -#else - -#error Configuration Error ! At least one USB mode support must be enabled ! (CONFIG_USB_FS_SUPPORT/CONFIG_USB_HS_SUPPORT/CONFIG_USB_SS_SUPPORT) - -#endif - } - else - { -#if defined(CONFIG_USB_SS_SUPPORT) - descriptor_ptr = (void *)&ctx->usb_config->ep_desc_ss; - descriptor_size = sizeof(ep_cfg_descriptor); -#elif defined(CONFIG_USB_HS_SUPPORT) - descriptor_ptr = (void *)&ctx->usb_config->ep_desc_hs; - descriptor_size = sizeof(struct usb_endpoint_descriptor_no_audio); -#elif defined(CONFIG_USB_FS_SUPPORT) - descriptor_ptr = (void *)&ctx->usb_config->ep_desc_fs; - descriptor_size = sizeof(struct usb_endpoint_descriptor_no_audio); -#else - -#error Configuration Error ! At least one USB mode support must be enabled ! (CONFIG_USB_FS_SUPPORT/CONFIG_USB_HS_SUPPORT/CONFIG_USB_SS_SUPPORT) - -#endif - } - -#if defined(CONFIG_USB_SS_SUPPORT) - switch(index) - { - case EP_DESCRIPTOR_IN: - memcpy(&ctx->ep_config[index]->ep_desc[0], &((SSEndPointsDesc*)descriptor_ptr)->ep_desc_in,descriptor_size); - memcpy(&ctx->ep_config[index]->ep_desc[1], &((SSEndPointsDesc*)descriptor_ptr)->ep_desc_in,descriptor_size); - break; - case EP_DESCRIPTOR_OUT: - memcpy(&ctx->ep_config[index]->ep_desc[0], &((SSEndPointsDesc*)descriptor_ptr)->ep_desc_out,descriptor_size); - memcpy(&ctx->ep_config[index]->ep_desc[1], &((SSEndPointsDesc*)descriptor_ptr)->ep_desc_out,descriptor_size); - break; - case EP_DESCRIPTOR_INT_IN: - memcpy(&ctx->ep_config[index]->ep_desc[0], &((SSEndPointsDesc*)descriptor_ptr)->ep_desc_int_in,descriptor_size); - memcpy(&ctx->ep_config[index]->ep_desc[1], &((SSEndPointsDesc*)descriptor_ptr)->ep_desc_int_in,descriptor_size); - break; - } -#else - switch(index) - { - case EP_DESCRIPTOR_IN: - memcpy(&ctx->ep_config[index]->ep_desc[0], &((EndPointsDesc*)descriptor_ptr)->ep_desc_in,descriptor_size); - memcpy(&ctx->ep_config[index]->ep_desc[1], &((EndPointsDesc*)descriptor_ptr)->ep_desc_in,descriptor_size); - break; - case EP_DESCRIPTOR_OUT: - memcpy(&ctx->ep_config[index]->ep_desc[0], &((EndPointsDesc*)descriptor_ptr)->ep_desc_out,descriptor_size); - memcpy(&ctx->ep_config[index]->ep_desc[1], &((EndPointsDesc*)descriptor_ptr)->ep_desc_out,descriptor_size); - break; - case EP_DESCRIPTOR_INT_IN: - memcpy(&ctx->ep_config[index]->ep_desc[0], &((EndPointsDesc*)descriptor_ptr)->ep_desc_int_in,descriptor_size); - memcpy(&ctx->ep_config[index]->ep_desc[1], &((EndPointsDesc*)descriptor_ptr)->ep_desc_int_in,descriptor_size); - break; - } -#endif - - log_cls::log(LOG_LEVEL_ALL, "init_ep (%d):\n",index); - PRINT_DEBUG_BUF(ctx->ep_config[index], sizeof(ep_cfg)); - - if(!ffs_mode) - { - if(open_ep) - { - ret = write(fd, ctx->ep_config[index], sizeof(ep_cfg)); - - if (ret != sizeof(ep_cfg)) - { - PRINT_ERROR("init_ep : Endpoint %s (%d) init failed ! : Write Error %d - %m",ctx->ep_path[index], index, ret); - goto init_ep_error; - } - } - } - else - { - log_cls::log(LOG_LEVEL_ALL, "init_ep (%d): FunctionFS Mode - Don't write the endpoint descriptor.\n",index); - } - - return fd; - -init_ep_error: - return 0; -} - -#include -bool now(struct timeval* tv) -{ - struct timezone tz = { 0 }; - bool ok = gettimeofday(tv, &tz) == 0; - - // tv->tv_sec -= 60 * tz.tz_minuteswest; - - return ok; -} -std::string time_now(void) // return '2022-11-30 10:38:42.123', no '.123' if with_ms was false -{ - struct timeval tv = { 0 }; - - if (!now(&tv)) - return ""; - - char buf[40] = { 0 }; - time_t t = tv.tv_sec; - struct tm* l = localtime(&t); - static int cnt = 0; - - sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d.%06d", l->tm_year + 1900, l->tm_mon + 1, l->tm_mday - , l->tm_hour, l->tm_min, l->tm_sec, tv.tv_usec); - - return buf; -} -std::string send_for_int(void) -{ - return "abcdefghijklmnopqrstuvwxyz/[]{}|+=ABCDEFGHIJKLMNOPQRSTUVWXYZ@#$%^&*()_+-=~<>;ENDOFINTERRUPTCONTENT!!!!"; -} -static void send_timer_tick(UsbDevice *dev, int type) -{ - std::string pre(type == EP_DESCRIPTOR_INT_IN ? "[Intr] " : "[Bulk] "); - int (UsbDevice::*sendf)(void*, int, int*) = type == EP_DESCRIPTOR_INT_IN ? &UsbDevice::write_int : &UsbDevice::write_bulk; - std::string (*content)(void) = type == EP_DESCRIPTOR_INT_IN ? send_for_int : time_now; - int err = 0, out = 0; - - printf("timer tick thread(%p - %s) running ...\n", pthread_self(), pre.c_str()); - while(1) - { - std::string cur(pre + content()); - printf("now: %s\n", cur.c_str()); - out = (dev->*sendf)(&cur[0], cur.length(), &err); - if(out != cur.length()) - printf("\tPartial data sent: %d/%d\n", out, cur.length()); - if(err == EBADF || err == ESHUTDOWN) - break; - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - printf("timer tick thread(%p - %s) exited.\n", pthread_self(), pre.c_str()); -} -static void read_bulk_thread(UsbDevice *dev) -{ - char buf[513] = {0}; - - printf("read_bulk_thread(%p) running ...\n", pthread_self()); - while(1) - { - int err = 0, - l = dev->read_bulk(buf, sizeof(buf) - 1, &err, false); - if(err == EBADF || err == ESHUTDOWN) - break; - buf[l] = 0; - printf("--Recived: %s\n", buf); - } - printf("read_bulk_thread(%p) exited.\n", pthread_self()); -} - -int UsbDevice::init_eps(usb_gadget * ctx, int ffs_mode, bool open_ep) -{ - if( !init_ep(ctx, EP_DESCRIPTOR_IN, ffs_mode, open_ep) && open_ep ) - goto init_eps_error; - - if( !init_ep(ctx, EP_DESCRIPTOR_OUT, ffs_mode, open_ep) && open_ep ) - goto init_eps_error; - - if( !init_ep(ctx, EP_DESCRIPTOR_INT_IN, ffs_mode, open_ep) && open_ep ) - goto init_eps_error; - -#ifdef EP_AUTO_SEND - bulk_sent_.reset(new std::thread(&send_timer_tick, this, EP_DESCRIPTOR_IN)); - bulk_read_.reset(new std::thread(&read_bulk_thread, this)); - int_sent_.reset(new std::thread(&send_timer_tick, this, EP_DESCRIPTOR_INT_IN)); -#endif - - return 0; - -init_eps_error: - return 1; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -#ifdef ASYNC_EP -static std::string get_value(const char* key) -{ - if(strcmp(key, "dev-sn") == 0) - return "20230330001A"; - - if(strcmp(key, "fwmver") == 0) - return "2023001"; - - return "not-supported"; -} -void dump_buf(uint8_t *data, int len) -{ - uint32_t addr = 0; - std::string asc(""); - for(int i = 0; i < len; ++i) - { - if((i % 16) == 0) - { - printf(" %s\n0x%08x ", asc.c_str(), addr); - addr += 16; - asc = ""; - } - else if((i % 8) == 0) - { - printf(" "); - } - - uint8_t v = data[i]; - printf("%02X ", v); - if(v >= 0x20 && v < 0x7f) - asc.append(1, v); - else - asc += "."; - } - if(asc.length()) - { - std::string pad(" "); - if(asc.length() <= 8) - pad.erase((16 - asc.length()) * 3 + 2); - else if(asc.length() < 16) - pad.erase((16 - asc.length()) * 3); - else - pad = ""; - printf("%s %s", pad.c_str(), asc.c_str()); - } - printf("\n"); - -} - -dyn_mem_ptr UsbDevice::unhandled_ep0(struct usb_functionfs_event* pev) -{ - return nullptr; -} -dyn_mem_ptr UsbDevice::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) -{ - dyn_mem_ptr reply = nullptr; - LPPACK_BASE pk = nullptr; - size_t base_head_size = sizeof(PACK_BASE); - - if(pack->size != base_head_size) - { - log_cls::log(LOG_LEVEL_ALL, "Unknown Packet with %d bytes:\n", *used); - dump_buf((uint8_t*)pack, *used); - reply = dyn_mem::memory(base_head_size); - LPPACK_BASE p = (LPPACK_BASE)reply->ptr(); - BASE_PACKET_REPLY(*p, PACK_CMD_INVALID, pack->pack_id, pack->cmd); - reply->set_len(base_head_size); - - return reply; - } - - switch(pack->cmd) - { - case PACK_CMD_SYNC: - *used = sizeof(PACK_BASE); - reply = dyn_mem::memory(base_head_size); - pk = (LPPACK_BASE)reply->ptr(); - BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, 0); - reply->set_len(base_head_size); - break; - case PACK_CMD_SETTING_GET_CUR: - if(*used < base_head_size + pack->payload_len) - *used = 0; - else - { - std::string val(get_value(pack->payload)); - LPCFGVAL cfg = nullptr; - - reply = dyn_mem::memory(base_head_size + sizeof(CFGVAL) + strlen(pack->payload) + 1 + val.length() + 1); - pk = (LPPACK_BASE)reply->ptr(); - BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, 0); - cfg = (LPCFGVAL)pk->payload; - cfg->val_size = val.length(); - 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()); - strcpy(cfg->data + cfg->name_off, pack->payload); - reply->set_len(base_head_size + pk->payload_len); - *used = base_head_size + pack->payload_len; - } - break; - case PACK_CMD_FILE_WRITE_REQ: - if(*used < pack->payload_len + pack->size) - { - *used = 0; - } - else - { - LPTXFILE pfi = (LPTXFILE)pack->payload; - std::string path(pfi->path); - int err = 0; - file_saver *saver = new file_saver(); - - err = saver->open(path.c_str(), pfi->size); - reply = dyn_mem::memory(base_head_size); - reply->set_len(base_head_size); - BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err); - *used = base_head_size + pack->payload_len; - if(err) - { - saver->release(); - saver = nullptr; - } - else - { - saver->set_packet_param(pack->cmd, pack->pack_id); - } - log_cls::log(LOG_LEVEL_DEBUG, "receive file (%u bytes): %s = %d\n", pfi->size, path.c_str(), err); - *required = dynamic_cast(saver); - } - break; - case PACK_CMD_FILE_READ_REQ: - if(*used < pack->payload_len + pack->size) - { - *used = 0; - } - else - { - LPTXFILE pfi = (LPTXFILE)pack->payload; - std::string path(pfi->path); - int err = 0; - file_reader *reader = new file_reader(); - - err = reader->open(path.c_str()); - reply = dyn_mem::memory(base_head_size + sizeof(TXFILE)); - reply->set_len(base_head_size + sizeof(TXFILE)); - BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err); - *used = base_head_size + pack->payload_len; - log_cls::log(LOG_LEVEL_DEBUG, "To send file '%s' with %u bytes = %d\n", path.c_str(), reader->get_rest(), err); - if(err) - { - reader->release(); - reader = nullptr; - } - else - { - ((LPPACK_BASE)reply->ptr())->payload_len = sizeof(TXFILE); - ((LPTXFILE)((LPPACK_BASE)reply->ptr())->payload)->size = reader->get_rest(); - reader->set_packet_param(pack->cmd, pack->pack_id); - } - *required = dynamic_cast(reader); - } - break; - } - - return reply; -} -void UsbDevice::do_system_command(const char* cmd) -{ - log_cls::log(LOG_LEVEL_ALL, "invoking system command: %s ...\n", cmd); - get_system_output(cmd); - log_cls::log(LOG_LEVEL_ALL, "invoked system command: %s.\n", cmd); -} -#endif diff --git a/device/gxx-linux/testusb/usb-rk3399/src/usbstring.cpp b/device/gxx-linux/testusb/usb-rk3399/src/usbstring.cpp deleted file mode 100644 index 9159250..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/src/usbstring.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/* - * uMTP Responder - * Copyright (c) 2018 - 2020 Viveris Technologies - * - * uMTP Responder is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * uMTP Responder is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 3 for more details. - * - * You should have received a copy of the GNU General Public License - * along with uMTP Responder; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - /** - * @file usbstring.c - * @brief USB Strings - * @author Jean-François DEL NERO - */ - -/* - * - * Note : This source file is based on the Linux kernel usbstring.c - * with the following Licence/copyright : - * - */ - -/* - * Copyright (C) 2003 David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - */ - -#include "buildconf.h" - -#include - -#include -#include -#include - -#include -#include - -#include "usbstring.h" - -/* From usbstring.[ch] */ - -static inline void put_unaligned_le16(uint16_t val, uint16_t *cp) -{ - uint8_t *p = (uint8_t *)cp; - - *p++ = (uint8_t) val; - *p++ = (uint8_t) (val >> 8); -} - -static int utf8_to_utf16le(const char *s, uint16_t *cp, unsigned len) -{ - int count = 0; - uint8_t c; - uint16_t uchar; - - /* this insists on correct encodings, though not minimal ones. - * BUT it currently rejects legit 4-byte UTF-8 code points, - * which need surrogate pairs. (Unicode 3.1 can use them.) - */ - while (len != 0 && (c = (uint8_t) *s++) != 0) { - if (c & 0x80) { - // 2-byte sequence: - // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx - if ((c & 0xe0) == 0xc0) { - uchar = (c & 0x1f) << 6; - - c = (uint8_t) *s++; - if ((c & 0xc0) != 0xc0) - goto fail; - c &= 0x3f; - uchar |= c; - - // 3-byte sequence (most CJKV characters): - // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx - } else if ((c & 0xf0) == 0xe0) { - uchar = (c & 0x0f) << 12; - - c = (uint8_t) *s++; - if ((c & 0xc0) != 0xc0) - goto fail; - c &= 0x3f; - uchar |= c << 6; - - c = (uint8_t) *s++; - if ((c & 0xc0) != 0xc0) - goto fail; - c &= 0x3f; - uchar |= c; - - /* no bogus surrogates */ - if (0xd800 <= uchar && uchar <= 0xdfff) - goto fail; - - // 4-byte sequence (surrogate pairs, currently rare): - // 11101110wwwwzzzzyy + 110111yyyyxxxxxx - // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx - // (uuuuu = wwww + 1) - // FIXME accept the surrogate code points (only) - - } else - goto fail; - } else - uchar = c; - put_unaligned_le16 (uchar, cp++); - count++; - len--; - } - return count; -fail: - return -1; -} - -int usb_gadget_get_string (struct usb_gadget_strings *table, int id, uint8_t *buf) -{ - struct usb_string *s; - int len; - - /* descriptor 0 has the language id */ - if (id == 0) { - buf [0] = 4; - buf [1] = USB_DT_STRING; - buf [2] = (uint8_t) table->language; - buf [3] = (uint8_t) (table->language >> 8); - return 4; - } - for (s = table->strings; s && s->str; s++) - if (s->id == id) - break; - - /* unrecognized: stall. */ - if (!s || !s->str) - return -EINVAL; - - /* string descriptors have length, tag, then UTF16-LE text */ - len = strlen (s->str); - if (len > 126) - len = 126; - memset (buf + 2, 0, 2 * len); /* zero all the bytes */ - len = utf8_to_utf16le(s->str, (uint16_t *)&buf[2], len); - if (len < 0) - return -EINVAL; - buf [0] = (len + 1) * 2; - buf [1] = USB_DT_STRING; - return buf [0]; -} - -int utf8_encode(char *out, uint32_t unicode) -{ - if (unicode <= 0x7F) - { - // ASCII - *out++ = (char) unicode; - *out++ = 0; - return 1; - } - else if (unicode <= 0x07FF) - { - // 2-bytes unicode - *out++ = (char) (((unicode >> 6) & 0x1F) | 0xC0); - *out++ = (char) (((unicode >> 0) & 0x3F) | 0x80); - *out++ = 0; - return 2; - } - else if (unicode <= 0xFFFF) - { - // 3-bytes unicode - *out++ = (char) (((unicode >> 12) & 0x0F) | 0xE0); - *out++ = (char) (((unicode >> 6) & 0x3F) | 0x80); - *out++ = (char) (((unicode >> 0) & 0x3F) | 0x80); - *out++ = 0; - return 3; - } - else if (unicode <= 0x10FFFF) - { - // 4-bytes unicode - *out++ = (char) (((unicode >> 18) & 0x07) | 0xF0); - *out++ = (char) (((unicode >> 12) & 0x3F) | 0x80); - *out++ = (char) (((unicode >> 6) & 0x3F) | 0x80); - *out++ = (char) (((unicode >> 0) & 0x3F) | 0x80); - *out++ = 0; - - return 4; - } - else - { - // error - return 0; - } -} - -int unicode2charstring(char * str, uint16_t * unicodestr, int maxstrsize) -{ - int i,j,ret; - int chunksize; - char tmpstr[8]; - - ret = 0; - i = 0; - while( *unicodestr ) - { - chunksize = utf8_encode((char*)&tmpstr, *unicodestr++); - - if(!chunksize) - { // Error -> default character - tmpstr[0] = '?'; - tmpstr[1] = 0; - chunksize = 1; - } - - if( (i + chunksize) < maxstrsize ) - { - for( j = 0 ; j < chunksize ; j++ ) - { - str[i] = tmpstr[j]; - i++; - } - } - else - { - str[ maxstrsize - 1 ] = 0; - ret = 1; - break; - } - }; - - if( i < maxstrsize ) - str[i] = 0; - - return ret; -} - -static int utf8_size(char c) -{ - int count = 0; - - while (c & 0x80) - { - c = c << 1; - count++; - } - - if(!count) - count = 1; - - return count; -} - -uint16_t utf2unicode(const unsigned char* pInput, int * ofs) -{ - uint8_t b1, b2, b3; - int utfsize; - uint16_t unicode_out; - - *ofs = 0; - - utfsize = utf8_size(*pInput); - - switch ( utfsize ) - { - case 1: - unicode_out = *pInput; - *ofs = 1; - return unicode_out; - break; - - case 2: - b1 = *pInput++; - b2 = *pInput++; - - if ( (b2 & 0xC0) != 0x80 ) - return 0x0000; - - unicode_out = ( ( (b1 & 0x1F) << 6 ) | (b2 & 0x3F) ) & 0xFF; - unicode_out |= (uint16_t)((b1 & 0x1F) >> 2) << 8; - *ofs = 2; - return unicode_out; - break; - - case 3: - b1 = *pInput++; - b2 = *pInput++; - b3 = *pInput++; - - if ( ((b2 & 0xC0) != 0x80) || ((b3 & 0xC0) != 0x80) ) - return 0x0000; - - unicode_out = (uint16_t)( ((b2 & 0x3F) << 6) | (b3 & 0x3F) ) & 0x00FF; - unicode_out |= (uint16_t)( ((b1 & 0xF) << 4) | ((b2 & 0x3F) >> 2 ) ) << 8; - - *ofs = 3; - - return unicode_out; - break; - - default: - *ofs = 0; - - return 0x0000; - break; - } - - return 0x0000; -} - -int char2unicodestring(char * unicodestr, int index, int maxsize, char * str, int unicodestrsize) -{ - uint16_t unicode; - int ofs, len, start; - - start = index; - len = 0; - ofs = 0; - do{ - unicode = utf2unicode((unsigned char*)str, &ofs); - str = str + ofs; - if(index + 2 >= maxsize) - return -1; - unicodestr[index++] = unicode & 0xFF; - unicodestr[index++] = (unicode >> 8) & 0xFF; - len++; - }while(unicode && ofs && index < unicodestrsize*2); - - if( len >= unicodestrsize) - { - if(start + ((unicodestrsize*2)-2) >= maxsize) - return -1; - - unicodestr[start + ((unicodestrsize*2)-2)] = 0x00; - unicodestr[start + ((unicodestrsize*2)-1)] = 0x00; - len = unicodestrsize; - } - - return len; -} diff --git a/device/gxx-linux/testusb/usb-rk3399/usbimageprocqueue.h b/device/gxx-linux/testusb/usb-rk3399/usbimageprocqueue.h deleted file mode 100644 index f6ed6bf..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/usbimageprocqueue.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once -#include -#include "imgproc.h" -#include "mutex" -#include "itransmit.h" -#include "inotify.h" -#include "ireceive.h" -#include "BlockingQueue.h" - -class UsbImageProcQueue -{ -public: - UsbImageProcQueue(NotifyPtr notify) - { - this->notify = notify; - } - - void push(MemoryPtr image,bool containsimg) - { - std::lock_guard lck(mx); - HGIntInfo info; - if(containsimg) - { - printf("UsbImageProcQueue::push\n"); - images.push(image); - //images.Put(image); - info.From = IMG; - info.Code = image->size(); - } - else - { - info = *((HGIntInfo*)image->data()); - } - if(notify) - notify->notify(&info, sizeof(info)); - } - - - MemoryPtr front() - { - std::lock_guard lck(mx); - - auto front = images.front(); - return front; - //return images.Front(); - } - - MemoryPtr pop() - { - std::lock_guard lck(mx); - if(images.size()>0) - { - printf("UsbImageProcQueue::pop\n"); - auto front = images.front(); - images.pop(); - //auto front=images.Take(); - return front; - } - return MemoryPtr(); - } - - bool empty() - { - std::lock_guard lck(mx); - return images.empty(); - //return images.Size()>0; - } - - int size() - { - std::lock_guard lck(mx); - return images.size(); - //return images.Size(); - } - - int front_datasize() - { - std::lock_guard lck(mx); - if(images.size()<1) - return 0; - auto img=images.front(); - return images.empty() ? 0 : images.front()->size(); - //return (images.Size()>0) ? 0 : images.Front()->size(); - } - - - void clear() - { - std::lock_guard lck(mx); - while(images.size()>0) - images.pop(); - } - -private: - std::queue images; - //BlockingQueue images; - NotifyPtr notify; - std::mutex mx; -}; \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/usbnotify.cpp b/device/gxx-linux/testusb/usb-rk3399/usbnotify.cpp deleted file mode 100644 index caf1095..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/usbnotify.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "usbnotify.h" -#include "usbdevice.h" -#include "StopWatch.h" -#include -#include - -UsbNotify::UsbNotify(std::shared_ptr usb) -: brun(true) -{ - this->usb= usb; - runThread.reset(new ThreadEx(&UsbNotify::run_notify, this)); -} - -UsbNotify::~UsbNotify() -{ - brun = false; - ae.notify_all(); -} - -void UsbNotify::notify(void* data, int size) -{ - if(!usb || !usb->is_connected()) - return; - - std::lock_guard lck(mx); - // StopWatch sw; - // while (msgs.empty() && sw.elapsed_ms() < 100); - - // if(!msgs.empty()) - // msgs = std::queue>(); - - std::vector msg(size); - memcpy(&msg[0],data,size); - msgs.push(msg); - //msgs.push(std::vector((unsigned char*)data, (unsigned char*)data + size)); - ae.notify_all(); -} - -void UsbNotify::clear() -{ - usb->abort_int(); - std::lock_guard lck(mx); - msgs = std::queue>(); -} - -void UsbNotify::run_notify() -{ - unsigned char buff[64]; - while(brun) - { - if (ae.wait(300000) && brun) - { - for(;;) - { - { - std::lock_guard lck(mx); - if(msgs.empty()) - break; - auto &data = msgs.front(); - memset(buff,0,sizeof(buff)); - std::copy(data.begin(), data.end(), buff); - } - - if (usb && usb->is_connected()) - usb->write_int(buff, sizeof(buff)); - - { - std::lock_guard lck(mx); - if(msgs.size()>0) - msgs.pop(); - } - } - } - } -} \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/usbnotify.h b/device/gxx-linux/testusb/usb-rk3399/usbnotify.h deleted file mode 100644 index 78c6035..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/usbnotify.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include "inotify.h" -#include "autoevent.hpp" -#include -#include -#include -#include - -class UsbDevice; - -class UsbNotify : public INotify -{ -public: - UsbNotify(std::shared_ptr usb); - virtual ~UsbNotify(); - virtual void notify(void* data, int size); - virtual void clear(); - -private: - void run_notify(); - - std::shared_ptr runThread; - AutoEvent ae; - std::mutex mx; - std::queue> msgs; - std::shared_ptr usb; - volatile bool brun; -}; \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/usbreceive.cpp b/device/gxx-linux/testusb/usb-rk3399/usbreceive.cpp deleted file mode 100644 index 4c453b0..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/usbreceive.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "usbreceive.h" -#include "memoryex.h" -#include "applog.h" -#include -#include "usbdevice.h" - -static std::string loggername = "UsbReceive"; - -UsbReceive::UsbReceive(std::shared_ptr t_usb) -{ - LOG_INIT(); - this->usb=t_usb; -} - - -UsbReceive::~UsbReceive() -{ - cannel(); -} - -int UsbReceive::read(MemoryPtr& memroy) -{ - int nread=0; - LOG_TRACE("rx start in"); - if (is_reading()) - return nread; - - runthread.reset(new ThreadEx([this, memroy]() { - LOG_TRACE("rx starting"); - if (usb && usb->is_connected()) - usb->read_bulk(memroy->data(), memroy->size()); - - LOG_TRACE("rx started"); - })); - return nread; -} - -int UsbReceive::read_bulk(void* data,unsigned int length) -{ - printf("(%p)perform read_bulk in UsbReceive object...\n", pthread_self()); - int nread=0; - if(usb.get()&&usb->is_connected()) - { - if(data != nullptr && length >0) - nread = usb->read_bulk(data,length); - else - LOG_TRACE("read_bulk uncorrect data ptr or length"); - } - printf("(%p)read_bulk in UsbReceive object OVER.\n", pthread_self()); - - return nread; -} - -bool UsbReceive::is_reading() -{ - return runthread&&runthread->is_runing(); -} - -void UsbReceive::cannel() -{ - if(runthread.get()) - runthread->cannel(); -} \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/usbreceive.h b/device/gxx-linux/testusb/usb-rk3399/usbreceive.h deleted file mode 100644 index 0dc014e..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/usbreceive.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include "ireceive.h" - -class UsbDevice; -class ThreadEx; - -class UsbReceive :public IReceive -{ -public: - UsbReceive(std::shared_ptr t_usb); - virtual ~UsbReceive(); - - virtual int read(MemoryPtr &memroy); - virtual int read_bulk(void* data,unsigned int length); - virtual bool is_reading(); - virtual void cannel(); - -private: - std::shared_ptr usb; - std::shared_ptr runthread; -}; diff --git a/device/gxx-linux/testusb/usb-rk3399/usbservice.cpp b/device/gxx-linux/testusb/usb-rk3399/usbservice.cpp deleted file mode 100644 index 7496ecf..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/usbservice.cpp +++ /dev/null @@ -1,239 +0,0 @@ -#include "usbservice.h" -#include -#include -#include -#include -#include "stringex.hpp" -#include -#include -#include "usbdevice.h" -#include "regsaccess.h" -#include "usbtransmit.h" -#include "usbreceive.h" -#include "usbnotify.h" -#include "applog.h" -#include "../../scanner/scannerregs.h" - -static const std::string loggername = "UsbService"; - -typedef struct -{ - int Command; - int Data; - int Length; -} USBCB; - -#define USB_REQ_GET_FPGA_REGS 0x40 -#define USB_REQ_SET_FPGA_REGS 0x41 -#define USB_REQ_GET_MOTOR_REGS 0x42 -#define USB_REQ_SET_MOTOR_REGS 0x43 - -#define USB_REQ_ACCES_DEV_LOG 0x50 - -#define USB_REQ_GET_DEV_STATUS 0x60 -#define USB_REQ_GET_DEV_CONFIGURATION 0x61 -#define USB_REQ_SET_DEV_CONFIGURATION 0x62 -#define USB_REQ_GET_DEV_REGS 0x63 -#define USB_REQ_SET_DEV_REGS 0x64 -#define USB_REQ_GET_DEV_LOG 0x65 -#define USB_REQ_SET_DEV_LOG 0x66 - -static bool read_regs(unsigned int *regs, int regindex, int creg, std::shared_ptr ®sacess) -{ - printf("read_regs enter ...\n"); - int index; - for (int i = 0; i < creg; i++) - { - index = regindex + i; - if (!regsacess->read(index, *(regs + i))) - { - LOG_ERROR(string_format("read error %d=%08x\n", index, regs[i])); - return false; - } - LOG_TRACE(string_format("read %d=%08x\n", index, regs[i])); - } - printf("read_regs exit ...\n"); - - return true; -} - -static bool write_regs(unsigned int *regs, int regindex, int creg, std::shared_ptr ®sacess) -{ - printf("write_regs enter ...\n"); - int index; - bool ret = true; - for (int i = 0; i < creg; i++) - { - index = regindex + i; - if (!regsacess->write(index, *(regs + i))) - { - LOG_ERROR(string_format("wirte error %d=%08x\n", index, regs[i])); - ret = false; - break; - } - LOG_TRACE(string_format("wirte %d=%08x\n", index, regs[i])); - } - printf("write_regs exit.\n"); - return ret; -} - -UsbService::UsbService(std::shared_ptr fgparegs, std::shared_ptr motorregs, std::shared_ptr scannerregs) : scanner_(nullptr) -{ - LOG_INIT(); - this->fgparegs = fgparegs; - this->motorregs = motorregs; - this->devregs = scannerregs.get(); - auto ctrl_handle = [&](int fd, struct usb_ctrlrequest *setup, unsigned char *buffer) -> bool - { - printf("req = %x, type = %x, ind = %x, len = %x, val = %x\n", setup->bRequest, setup->bRequestType, setup->wIndex, setup->wLength, setup->wValue); - if (!(setup->bRequestType & USB_TYPE_VENDOR) || (setup->bRequestType & USB_RECIP_MASK) != USB_RECIP_DEVICE) - return false; - - static std::string logstring; - unsigned int *regs = (unsigned int *)buffer; - int creg = 0; - if (!(setup->wLength % 4)) - creg = setup->wLength / 4; - - int regindex = setup->wValue; - - switch (setup->bRequest) - { - case USB_REQ_GET_FPGA_REGS: - if ((setup->bRequestType & USB_DIR_IN) && creg && this->fgparegs) - { - if (!read_regs(regs, regindex, creg, this->fgparegs)) - return false; - ::write(fd, buffer, setup->wLength); - return true; - } - break; - case USB_REQ_SET_FPGA_REGS: - if (!(setup->bRequestType & USB_DIR_IN) && creg && this->fgparegs) - { - ::read(fd, buffer, setup->wLength); - if (!write_regs(regs, regindex, creg, this->fgparegs)) - return false; - return true; - } - break; - - case USB_REQ_GET_MOTOR_REGS: - if ((setup->bRequestType & USB_DIR_IN) && creg && this->motorregs) - { - if (!read_regs(regs, regindex, creg, this->motorregs)) - return false; - ::write(fd, buffer, setup->wLength); - return true; - } - break; - case USB_REQ_SET_MOTOR_REGS: - if (!(setup->bRequestType & USB_DIR_IN) && creg && this->motorregs) - { - ::read(fd, buffer, setup->wLength); - if (!write_regs(regs, regindex, creg, this->motorregs)) - return false; - return true; - } - break; - - case USB_REQ_GET_DEV_REGS: - if ((setup->bRequestType & USB_DIR_IN) && creg && this->devregs) - { - if (!read_regs(regs, regindex, creg, this->devregs)) - return false; - ::write(fd, buffer, setup->wLength); - return true; - } - break; - case USB_REQ_SET_DEV_REGS: - if (!(setup->bRequestType & USB_DIR_IN) && creg && this->devregs) - { - ::read(fd, buffer, setup->wLength); - if (!write_regs(regs, regindex, creg, this->devregs)) - return false; - return true; - } - break; - case USB_REQ_ACCES_DEV_LOG: - if (setup->wLength != 64) - return false; - - if (!(setup->bRequestType & USB_DIR_IN)) - { - ::read(fd, buffer, setup->wLength); - buffer[64 - 1] = 0; - logstring = (char *)buffer; - return true; - } - else - { - memset(buffer, 0, 64); - if (!logstring.empty()) - memcpy(buffer, logstring.data(), logstring.size()); - ::write(fd, buffer, setup->wLength); - return true; - } - break; - - case USB_REQ_GET_DEV_LOG: - if ((setup->wLength == 4) && (setup->bRequestType & USB_DIR_IN) && log_get_level(logstring, regindex, *((int *)regs))) - { - ::write(fd, buffer, setup->wLength); - return true; - } - break; - case USB_REQ_SET_DEV_LOG: - if ((setup->wLength == 4) && !(setup->bRequestType & USB_DIR_IN)) - { - ::read(fd, buffer, setup->wLength); - return log_set_level(logstring, regindex, *((int *)regs)); - } - break; - default: - break; - } - - return false; - }; - - auto connected_call = [this](bool connected) - { - printf("PNP event: %s\n", connected ? "connected" : "disconnect"); - notify()->clear(); - if (m_usbconnect) - m_usbconnect(connected); - LOG_TRACE(string_format("connect status:%s", connected ? "connected" : "disconnect")); - }; - - usb.reset(new UsbDevice(ctrl_handle, connected_call)); -} - -UsbService::~UsbService() -{ -} - -std::shared_ptr UsbService::transmiter() -{ - return transmit ? transmit : (transmit = std::shared_ptr(new UsbTransmit(usb))); -} - -std::shared_ptr UsbService::receiver() -{ - return receiv ? receiv : (receiv = std::shared_ptr(new UsbReceive(usb))); -} -void UsbService::set_scannerregs(std::shared_ptr scannerregs) -{ - scanner_ = scannerregs.get(); - this->devregs = dynamic_cast(scanner_); -} - -std::shared_ptr UsbService::notify() -{ - return noti ? noti : (noti = std::shared_ptr(new UsbNotify(usb))); -} - -void UsbService::set_onconnect_call(std::function usbhotplugcall) -{ - m_usbconnect = usbhotplugcall; -} \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/usbservice.h b/device/gxx-linux/testusb/usb-rk3399/usbservice.h deleted file mode 100644 index 2040aff..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/usbservice.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once -#include -#include -#include -#include - -class IRegsAccess; - -class UsbDevice; -class INotify; -class ITransmit; -class IReceive; -class ScannerRegAccess; - -class UsbService -{ - ScannerRegAccess* scanner_; - -public: - UsbService(std::shared_ptr fgparegs, std::shared_ptr motorregs, std::shared_ptr scannerregs = nullptr); - virtual ~UsbService(); - - - std::shared_ptr transmiter(); - std::shared_ptr notify(); - std::shared_ptr receiver(); - void set_onconnect_call(std::function usbhotplugcall); - void set_scannerregs(std::shared_ptr scannerregs); - -private: - std::shared_ptr usb; - std::shared_ptr fgparegs; - std::shared_ptr motorregs; - IRegsAccess* devregs; - std::shared_ptr transmit; - std::shared_ptr noti; - std::shared_ptr receiv; - std::function m_usbconnect; -}; \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/usbtransmit.cpp b/device/gxx-linux/testusb/usb-rk3399/usbtransmit.cpp deleted file mode 100644 index 4456a4c..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/usbtransmit.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "usbtransmit.h" -#include "usbdevice.h" -#include -#include -#include "applog.h" -#include "memoryex.h" -#include -#include "stringex.hpp" - -static std::string loggername = "UsbTransmit"; - -UsbTransmit::UsbTransmit(std::shared_ptr usb) -{ - LOG_INIT(); - this->usb = usb; -} - -UsbTransmit::~UsbTransmit() -{ - cannel(); -} - -void UsbTransmit::write(MemoryPtr memroy) -{ - LOG_TRACE("tx start in"); - if (is_writing()) - { - LOG_TRACE("send image data error "); - printf("send image data error "); - return; - } - static int indextransfer=0; - runthread.reset(new ThreadEx([this, memroy]() { - if (usb && usb->is_connected()) - { - LOG_TRACE("tx starting"); - LOG_TRACE(string_format("tx starting transfer index =%d mmy size = %d",++indextransfer,memroy->size())); - //printf("\n tx starting transfer index =%d mmy size = %d",++indextransfer,memroy->size()); - int num= usb->write_bulk(memroy->data(), memroy->size()); - LOG_TRACE("tx end\n"); - } - })); -} - -int UsbTransmit::write_bulk(void* data,int size) -{ - int nwrite = 0; - if (usb && usb->is_connected()) - nwrite = usb->write_bulk(data, size); - return nwrite; -} - -bool UsbTransmit::is_writing() -{ - LOG_TRACE("checking UsbTransmit is_writing"); - auto ret=runthread && runthread->is_runing(); - LOG_TRACE(string_format("checking UsbTransmit done ret= %s ",ret?"true":"false")); - return ret; -} - -void UsbTransmit::cannel() -{ - if(runthread) - runthread->cannel(); -} \ No newline at end of file diff --git a/device/gxx-linux/testusb/usb-rk3399/usbtransmit.h b/device/gxx-linux/testusb/usb-rk3399/usbtransmit.h deleted file mode 100644 index bd83f5d..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/usbtransmit.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include "itransmit.h" -#include -#include -#include - -class UsbDevice; - -class UsbTransmit : public ITransmit -{ -public: - UsbTransmit(std::shared_ptr usb); - virtual ~UsbTransmit() override; - virtual void write(MemoryPtr memroy) override; - virtual bool is_writing() override; - virtual void cannel() override; - virtual int write_bulk(void* data,int size) override; -private: - std::shared_ptr usb; - std::shared_ptr runthread; - -}; diff --git a/device/gxx-linux/testusb/usb-rk3399/xmake.lua b/device/gxx-linux/testusb/usb-rk3399/xmake.lua deleted file mode 100644 index 16c06a6..0000000 --- a/device/gxx-linux/testusb/usb-rk3399/xmake.lua +++ /dev/null @@ -1,11 +0,0 @@ -add_rules("mode.debug", "mode.release") - -target("gusb") - set_kind("static") - add_syslinks("pthread") - add_files("*.cpp", "src/*.cpp", "src/common/*.cpp") - add_includedirs("inc") - add_includedirs("src/common") - add_includedirs(".", { public = true}) - add_packages("common") - add_deps("regs", "gimgproc", "applog") \ No newline at end of file diff --git a/device/gxx-linux/testwakeup/main.cpp b/device/gxx-linux/testwakeup/main.cpp new file mode 100644 index 0000000..d2c2604 --- /dev/null +++ b/device/gxx-linux/testwakeup/main.cpp @@ -0,0 +1,50 @@ +#include +#include +#include "scanner.h" +#include "scannerregs.h" +#include "usbservice.h" +#include "motorboard.h" +#include "ICapturer.h" +#include "Capturer.h" +#include "MonoCapturer.h" +#include "imageusbhandler.h" +#include "uartregsaccess.h" +#include "wakeup.hpp" + +using namespace std; + +int main() +{ + remove("./out.text"); + std::shared_ptr wake; + wake.reset(new WakeUp()); + std::shared_ptr uart; + wake->power_off(); + uint reg_val = 0; + std::uint64_t index =0; + std::uint64_t error =0; + while(true) + { + index++; + std::this_thread::sleep_for(std::chrono::seconds(600)); + wake->power_on(); + std::this_thread::sleep_for(std::chrono::seconds(3)); + uart.reset(new UartRegsAccess("/dev/ttyUSB0", 921600, 0x03, 0x83)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if(!uart->read(15,reg_val)) + { + error++; + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + uart.reset(); + std::this_thread::sleep_for(std::chrono::seconds(120)); + wake->power_off(); + std::string str = "测试次数 = "+to_string(index)+" 异常次数 = "+to_string(error); + printf("\n%s",str.c_str()); + std::ofstream o("./out.text"); + o << str; + o.close(); + + } + return 0; +} \ No newline at end of file diff --git a/device/gxx-linux/testwakeup/xmake.lua b/device/gxx-linux/testwakeup/xmake.lua new file mode 100644 index 0000000..4dc81e6 --- /dev/null +++ b/device/gxx-linux/testwakeup/xmake.lua @@ -0,0 +1,8 @@ +add_rules("mode.debug", "mode.release") + +target("testwakeup") + set_kind("binary") + add_files("*.cpp") + add_syslinks("pthread") + add_deps("gscanner","regs") + add_packages("common") \ No newline at end of file diff --git a/device/gxx-linux/tinyfsm-master/COPYING b/device/gxx-linux/tinyfsm-master/COPYING new file mode 100644 index 0000000..11104ae --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/COPYING @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2012-2018 Axel Burri + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/device/gxx-linux/tinyfsm-master/ChangeLog b/device/gxx-linux/tinyfsm-master/ChangeLog new file mode 100644 index 0000000..1742bf2 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/ChangeLog @@ -0,0 +1,33 @@ +tinyfsm-0.3.2 + + * Add TINYFSM_NOSTDLIB compile option. + * Remove static asserts on transit functions. + * Fix elevator example. + +tinyfsm-0.3.1 + + * Bugfix (workaround) for compiler bug in gcc < 7.0: define template + specialization for FSM_INITIAL_STATE in "namespace tinyfsm" block. + +tinyfsm-0.3.0 + + * Bugfix: set initial state on all state machines before entering + states in FsmList::start(). + * Add Fsm::start() function (identical interface as FsmList). + * Add reset() functionality to Fsm and FsmList class. + * Add MooreMachine and MealyMachine class. + * Add API examples: simple_switch, resetting_switch, multiple_switch, + debugging_switch, mealy_machine, moore_machine. + * Relax access specifiers for Fsm::state() access function. + * Remove debug code. + +tinyfsm-0.2.0 + + * Use Fsm::initialize() for initialization (instead of + Fsm::initial_state). + * Change license to MIT + +tinyfsm-0.1.0 + + * Initial revision + * Note that this release was originally named "v0.10" diff --git a/device/gxx-linux/tinyfsm-master/README.md b/device/gxx-linux/tinyfsm-master/README.md new file mode 100644 index 0000000..c2aa9af --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/README.md @@ -0,0 +1,95 @@ +TinyFSM +======= + +TinyFSM is a simple finite state machine library for C++, designed for +optimal performance and low memory footprint. This makes it ideal for +real-time operating systems. The concept is very simple, allowing the +programmer to fully understand what is happening behind the scenes. It +provides a straightforward way of mapping your state machine charts +into source code. + +TinyFSM basically wraps event dispatching into function calls, making +event dispatching equally fast to calling (or even inlining) a +function. Even in the worst case, dispatching leads to nothing more +than a single vtable lookup and function call! + +Key Features: + + - Entry/exit actions + - Event actions + - Transition functions + - Transition conditions + - Event payload (classes) + - Inheritance of states and action functions + +TinyFSM benefits from the C++11 template metaprogramming features like +variadic templates, and does not depend on RTTI, exceptions or any +external library. + + +Official home page: + +Current version: `0.3.2` + + +Documentation +------------- + +You can find the main documentation in the `doc/` directory of the +TinyFSM project. The latest version is also available +[online](https://digint.ch/tinyfsm/doc/introduction.html). + + +Installation +------------ + +TinyFSM is a header-only library, no special installation steps are +needed. Just point your compiler to the "include" directory. + + +Donate +------ + +So TinyFSM has proven useful for you? + +I will definitively continue developing TinyFSM for free, but if you +want to support me you can do so: + +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QZQE9HY6QHDHS) + + +Development +----------- + +The source code for TinyFSM is managed using Git: + + git clone https://dev.tty0.ch/tinyfsm.git + +Mirror on GitHub: + + git clone https://github.com/digint/tinyfsm.git + +If you would like to contribute or have found bugs, visit the [TinyFSM +project page on GitHub] and use the [issues tracker] there. + + [TinyFSM project page on GitHub]: http://github.com/digint/tinyfsm + [issues tracker]: http://github.com/digint/tinyfsm/issues + + +Contact +------- + +For questions and suggestions regarding TinyFSM, success or failure +stories, and any other kind of feedback, please feel free to contact +the author (the email address can be found in the sources). + + +License +------- + +TinyFSM is [Open Source] software. It may be used for any purpose, +including commercial purposes, at absolutely no cost. It is +distributed under the terms of the [MIT license]. + + [Open Source]: http://www.opensource.org/docs/definition.html + [MIT license]: http://www.opensource.org/licenses/mit-license.html diff --git a/device/gxx-linux/tinyfsm-master/doc/10-Introduction.md b/device/gxx-linux/tinyfsm-master/doc/10-Introduction.md new file mode 100644 index 0000000..b9186f3 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/doc/10-Introduction.md @@ -0,0 +1,28 @@ +Introduction +============ + +TinyFSM is a simple finite state machine library for C++, designed for +optimal performance and low memory footprint. This makes it ideal for +real-time operating systems. The concept is very simple, allowing the +programmer to fully understand what is happening behind the scenes. It +provides a straightforward way of mapping your state machine charts +into source code. + +TinyFSM basically wraps event dispatching into function calls, making +event dispatching equally fast to calling (or even inlining) a +function. Even in the worst case, dispatching leads to nothing more +than a single vtable lookup and function call! + +Key Features +------------ + +- Entry/exit actions +- Event actions +- Transition functions +- Transition conditions +- Event payload (classes) +- Inheritance of states and action functions + +TinyFSM benefits from the C++11 template metaprogramming features like +variadic templates, and does not depend on RTTI, exceptions or any +external library. diff --git a/device/gxx-linux/tinyfsm-master/doc/20-Installation.md b/device/gxx-linux/tinyfsm-master/doc/20-Installation.md new file mode 100644 index 0000000..78fa3f1 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/doc/20-Installation.md @@ -0,0 +1,68 @@ +Installation +============ + +TinyFSM is an header-only library, no special installation steps are +needed. Just point your compiler to the "include" directory, and in +your source files: + + #include + + +Prerequisites +------------- + +TinyFSM requires a compiler supporting the C++11 language standard +("-std=c++11" in gcc). + +TinyFSM does not depend on RTTI, exceptions or any external library. +If you need to compile without standard libraries (e.g. in conjunction +with `-nostdlib` linker option), add `-DTINYFSM_NOSTDLIB` to the +compiler options: this removes all dependencies on the standard +library by disabling some compile-time type checks. + + +Building the Elevator Example +----------------------------- + +Change to the elevator example directory and compile the sources: + + $ cd examples/elevator + $ make + +Our elevator has call buttons on every floor, sensors reporting the +current position, and an alarm button for emergency. These actors can +be triggered via a simple command interface: + + $ ./elevator + Motor: stopped + Motor: stopped + c=Call, f=FloorSensor, a=Alarm, q=Quit ? + +Let's call the elevator to floor 2: + + c=Call, f=FloorSensor, a=Alarm, q=Quit ? c + Floor ? 2 + Motor: moving up + c=Call, f=FloorSensor, a=Alarm, q=Quit ? + +Now the elevator is moving up, and we need to trigger the floor sensor: + + c=Call, f=FloorSensor, a=Alarm, q=Quit ? f + Floor ? 1 + Reached floor 1 + c=Call, f=FloorSensor, a=Alarm, q=Quit ? f + Floor ? 2 + Reached floor 2 + Motor: stopped + c=Call, f=FloorSensor, a=Alarm, q=Quit ? + +Now we simulate a sensor defect: + + c=Call, f=FloorSensor, a=Alarm, q=Quit ? c + Floor ? 1 + Motor: moving down + c=Call, f=FloorSensor, a=Alarm, q=Quit ? f + Floor ? 2 + Floor sensor defect (expected 1, got 2) + *** calling maintenance *** + Motor: stopped diff --git a/device/gxx-linux/tinyfsm-master/doc/30-Concepts.md b/device/gxx-linux/tinyfsm-master/doc/30-Concepts.md new file mode 100644 index 0000000..b0853d6 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/doc/30-Concepts.md @@ -0,0 +1,38 @@ +Concepts +======== + +Keep it Simple +-------------- + +By design, TinyFSM implements only the very basics needed for +designing state machines. For many people, it is important to know +what a library is doing when making a decision for a specific library. + + +State Definition +---------------- + +States are derived classes from a base FSM state, providing react() +functions for every event, as well as entry() and exit() functions. + + +Event Dispatching +----------------- + +TinyFSM does not hold state/event function tables like most other +state machine processors do. Instead, it keeps a pointer to the +current state (having the type of the state machine base +class). Dispatching an event simply calls the react() function of the +current state, with the event class as argument. This results in a +single vtable lookup and a function call, which is very efficient! + +Event dispatching on an FsmList<> are simply dispatch() calls to all +state machines in the list. + + +Header-Only Library +------------------- + +The TinyFSM library consist entirely of header files containing +templates, and requires no separately-compiled library binaries or +special treatment when linking. diff --git a/device/gxx-linux/tinyfsm-master/doc/40-Usage.md b/device/gxx-linux/tinyfsm-master/doc/40-Usage.md new file mode 100644 index 0000000..5ad931b --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/doc/40-Usage.md @@ -0,0 +1,238 @@ +Usage +===== + +Refer to the [API examples](/examples/api/) provided with the TinyFSM +package for a quick overview. Recommended starting points: + + - [Simple Switch](/examples/api/simple_switch.cpp) + - [Moore Machine](/examples/api/moore_machine.cpp) + - [Elevator Project](/examples/elevator/) + +For an example in an RTOS environment, see the [stm32f103stk-demo] of +the [OpenMPTL] project. Starting points: + + - [screen.hpp](https://github.com/digint/openmptl/tree/master/projects/stm32f103stk-demo/src/screen.hpp) + : TinyFSM declarations. + - [kernel.cpp](https://github.com/digint/openmptl/tree/master/projects/stm32f103stk-demo/src/kernel.cpp) + : Poll input and trigger events. + + [OpenMPTL]: https://digint.ch/openmptl/ + [stm32f103stk-demo]: https://github.com/digint/openmptl/tree/master/projects/stm32f103stk-demo + + +The examples in the documentation below are mainly based on the +"Elevator Project" example. + + +### 1. Declare Events + +Declare events that your state machine will listen to. Events are +classes derived from the tinyfsm::Event class. + +Example: + + struct FloorEvent : tinyfsm::Event + { + int floor; + }; + + struct Call : FloorEvent { }; + struct FloorSensor : FloorEvent { }; + struct Alarm : tinyfsm::Event { }; + +In the example above, we declare three events. Note that events are +regular classes, which are passed as arguments to the react() members +of a state class. In this example, we use a member variable "floor", +which is used to specify the floor number on "Call" and "FloorSensors" +events. + + +### 2. Declare the State Machine Class + +Declare your state machine class. State machines are classes derived +from the tinyfsm::Fsm template class, where T is the type name of the +state machine itself. + +You need to declare the following public members: + + - react() function for each event + - entry() and exit() functions + +Example: + + class Elevator + : public tinyfsm::Fsm + { + public: + /* default reaction for unhandled events */ + void react(tinyfsm::Event const &) { }; + + virtual void react(Call const &); + virtual void react(FloorSensor const &); + void react(Alarm const &); + + virtual void entry(void) { }; /* entry actions in some states */ + void exit(void) { }; /* no exit actions */ + }; + + +Note that you are free to declare the functions non-virtual if you +like. This has implications on the execution speed: In the example +above, the react(Alarm) function is declared non-virtual, as all states +share the same reaction for this event. This makes code execution +faster when dispatching the "Alarm" event, since no vtable lookup is +needed. + + +### 3. Declare the States + +Declare the states of your state machine. States are classes derived +from the state machine class. + +Note that state classes are *implicitly instantiated*. If you want to +reuse states in multiple state machines, you need to declare them as +templates (see `/examples/api/multiple_switch.cpp`). + +Example: + + class Panic + : public Elevator + { + void entry() override; + }; + + class Moving + : public Elevator + { + void react(FloorSensor const &) override; + }; + + class Idle + : public Elevator + { + void entry() override; + void react(Call const & e) override; + }; + + +In this example, we declare three states. Note that the "elevator" +example source code does not declare the states separately, but rather +defines the code directly in the declaration. + + +### 4. Implement Actions and Event Reactions + +In most cases, event reactions consist of one or more of the following +steps: + + - Change some local data + - Send events to other state machines + - Transit to different state + +**Important**: +Make sure that the `transit<>()` function call is the last command +executed within a reaction function! + +**Important**: +Don't use `transit<>()` in entry/exit actions! + +Example: + + void Idle::entry() { + send_event(MotorStop()); + } + + void Idle::react(Call const & e) { + dest_floor = e.floor; + + if(dest_floor == current_floor) + return; + + /* lambda function used for transition action */ + auto action = [] { + if(dest_floor > current_floor) + send_event(MotorUp()); + else if(dest_floor < current_floor) + send_event(MotorDown()); + }; + + transit(action); + }; + + +In this example, we use a lambda function as transition action. The +`transit<>()` function does the following: + + 1. Call the exit() function of the current state + 2. Call the the transition action if provided + 3. Change the current state to the new state + 4. Call the entry() function of the new state + +Note that you can also pass condition functions to the `transit<>()` +function. + + +### 5. Define the Initial State + +Use the macro `FSM_INITIAL_STATE(fsm, state)` for defining the initial +state (or "start state") of your state machine: + +Example: + + FSM_INITIAL_STATE(Elevator, Idle) + +This sets the current state of the "Elevator" state machine to "Idle". +More specifially, it defines a template specialization for +`Fsm::set_initial_state()`, setting the current state to +Idle. + + +### 6. Define Custom Initialization + +If you need to perform custom initialization, you can override the +reset() member function in your state machine class. If you are using +state variables, you can re-instantiate your states by calling +`tinyfsm::StateList::reset()`. + +Example: + + class Switch : public tinyfsm::Fsm + { + public: static void reset(void) { + tinyfsm::StateList::reset(); // reset all states + myvar = 0; + ... + } + ... + } + +Make sure to always set the current state, or you'll end up with a +null pointer dereference. + + +### 7. Use FsmList for Event Dispatching + +You might have noticed some calls to a send_event() function in the +example above. This is NOT a function provided with TinyFSM. Since +event dispatching can be implemented in several ways, TinyFSM leaves +this open to you. The "elevator" example implements the send_event() +function as *direct event dispatching*, without using event +queues. This has the advantage that execution is much faster, since no +RTTI is needed and the decision which function to call for an event +class is made at compile-time. On the other hand, special care has to +be taken when designing the state machines, in order to avoid loops. + +Code from "fsmlist.hpp": + + typedef tinyfsm::FsmList fsm_list; + + template + void send_event(E const & event) + { + fsm_list::template dispatch(event); + } + +Here, send_event() dispatches events to all state machines in the +list. It is important to understand that this approach comes with no +performance penalties at all, as long as the default reaction is +defined empty within the state machine declaration. diff --git a/device/gxx-linux/tinyfsm-master/doc/50-API.md b/device/gxx-linux/tinyfsm-master/doc/50-API.md new file mode 100644 index 0000000..44fcf17 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/doc/50-API.md @@ -0,0 +1,206 @@ +API Reference +============= + +`#include ` + + +Class Diagram +------------- + ....... + +--------------------------------------: T : + | tinyfsm::FsmList :.....: + +-----------------------------------------| + | [+] set_initial_state() <> | + | [+] reset() <> | + | [+] enter() <> | + | [+] start() <> | + | [+] dispatch(Event) <> | + +-----------------------------------------+ + + + ....... + +--------------------------------------: T : + | tinyfsm::Fsm :.....: + +-----------------------------------------| + | [+] state() <> | + | [+] set_initial_state() <> | + | [+] reset() <> | + | [+] enter() <> | + | [+] start() <> | + | [+] dispatch(Event) <> | + | [#] transit() | + | [#] transit(Action) | + | [#] transit(Action, Condition) | + +-----------------------------------------+ + # + | + | + +---------------------+ + | MyFSM | + +---------------------+ + | [+] entry() | + | [+] exit() | + | [+] react(EventX) | + | [+] react(EventY) | + | ... | + +---------------------+ + # + | + +-------------+-------------+ + | | | + +---------+ +---------+ +---------+ + | State_A | | State_B | | ... | + +---------+ +---------+ +---------+ + + + [#] protected + [+] public + [-] private + + +template< typename F > class Fsm +-------------------------------- + +### State Machine Functions + + * `template< typename S > static constexpr S & state(void)` + + Returns a reference to a (implicitly instantiated) state S. Allows + low-level access to all states; + + + * `static void set_initial_state(void)` + + Function prototype, must be defined (explicit template + specialization) for every state machine class (e.g. by using the + `FSM_INITIAL_STATE(fsm, state`) macro). Sets current state to + initial (start) state. + + + * `static void reset(void)` + + Empty function, can be overridden by state machine class in order to + perform custom initialization (e.g. set static state machine + variables, or reset states using `StateList::reset()`) + or directly via the `state()` instance). + + Note that this function is NOT called on start(). + + See example: `/examples/api/resetting_switch.cpp` + + * `static void enter(void)` + + Helper function, usually not needed to be used directly: + calls entry() function of current state. + + + * `static void start()` + + Sets the initial (start) state and calls its entry() function. + + + * `template< typename E > static void dispatch(E const &)` + + Dispatch an event to the current state of this state machine. + + +### State Transition Functions + + * `template< typename S > void transit(void)` + + Transit to a new state: + + 1. Call exit() function on current state + 2. Set new current state to S + 3. Call entry() function on new state + + + * `template< typename S, typename ActionFunction > void transit(ActionFunction)` + + Transit to a new state, with action function: + + 1. Call exit() function on current state + 2. Call ActionFunction + 3. Set new current state to S + 4. Call entry() function on new state + + + * `template< typename S, typename ActionFunction, typename ConditionFunction > void transit(ActionFunction, ConditionFunction)` + + Transit to a new state only if ConditionFunction returns true. + Shortcut for: `if(ConditionFunction()) transit(ActionFunction);`. + + +### Derived Classes + +#### template< typename F > class MooreMachine + +Moore state machines have entry actions, but no exit actions: + + * `virtual void entry(void) { }` + + Entry action, not enforcing. Can be enforced by declaring pure + virtual: `virtual void entry(void) = 0` + + * `void exit(void) { }` + + No exit actions. + +See example: `/examples/api/more_machine.cpp` + +#### template< typename F > class MealyMachine + +Mealy state machines do not have entry/exit actions: + + * `void entry(void) { }` + + No entry actions. + + * `void exit(void) { }` + + No exit actions. + +*Input actions* are modeled in react(), conditional dependent of event +type or payload and using `transit<>(ActionFunction)`. + +See example: `/examples/api/mealy_machine.cpp` + + +template< typename... FF > struct FsmList +----------------------------------------- + + * `static void set_initial_state(void)` + + Calls set_initial_state() on all state machines in the list. + + + * `static void reset()` + + Calls reset() on all state machines in the list. + + + * `static void enter()` + + Calls enter() on all state machines in the list. + + + * `static void start()` + + Sets the initial (start) state for all state machines in list, then + call all entry() functions. + + + * `template< typename E > static void dispatch(E const &)` + + Dispatch an event to the current state of all the state machines in + the list. + + +template< typename... SS > struct StateList +------------------------------------------- + + * `static void reset(void)` + + Re-instantiate all states in the list, using copy-constructor. + + See example: `/examples/api/resetting_switch.cpp` diff --git a/device/gxx-linux/tinyfsm-master/doc/60-Development.md b/device/gxx-linux/tinyfsm-master/doc/60-Development.md new file mode 100644 index 0000000..24ad0e1 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/doc/60-Development.md @@ -0,0 +1,26 @@ +Development +=========== + +Source Code Repository +---------------------- + +The source code for TinyFSM is managed using Git: + + git clone https://dev.tty0.ch/tinyfsm.git + +Mirror on GitHub: + + git clone https://github.com/digint/tinyfsm.git + + +How to Contribute +----------------- + +Your contributions are welcome! + +If you would like to contribute or have found bugs, visit the [TinyFSM +project page on GitHub] and use the [issues tracker] there, or contact +the author via email. + + [TinyFSM project page on GitHub]: http://github.com/digint/tinyfsm + [issues tracker]: http://github.com/digint/tinyfsm/issues diff --git a/device/gxx-linux/tinyfsm-master/doc/70-License.md b/device/gxx-linux/tinyfsm-master/doc/70-License.md new file mode 100644 index 0000000..6a4da72 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/doc/70-License.md @@ -0,0 +1,9 @@ +License +======= + +TinyFSM is [Open Source] software. It may be used for any purpose, +including commercial purposes, at absolutely no cost. It is +distributed under the terms of the [MIT license]. + + [Open Source]: http://www.opensource.org/docs/definition.html + [MIT license]: http://www.opensource.org/licenses/mit-license.html diff --git a/device/gxx-linux/tinyfsm-master/examples/api/Makefile b/device/gxx-linux/tinyfsm-master/examples/api/Makefile new file mode 100644 index 0000000..63b110e --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/Makefile @@ -0,0 +1,63 @@ +# Compiler prefix, in case your default compiler does not implement all C++11 features: +#CROSS = /opt/toolchain/x86_64-pc-linux-gnu-gcc-4.7.0/bin/x86_64-pc-linux-gnu- + +# HINT: g++ -Q -O2 --help=optimizers +OPTIMIZER = -Os + +CC = $(CROSS)gcc +CXX = $(CROSS)g++ +SIZE = size -d +RM = rm -f + +SRC_DIRS = . +INCLUDE = -I ../../include + +SRCS = $(wildcard $(addsuffix /*.cpp, $(SRC_DIRS))) +OBJS = $(SRCS:.cpp=.o) +DEPENDS = $(OBJS:.o=.d) + +EXE = $(SRCS:.cpp=) + + +#------------------------------------------------------------------------------ +# flags +# + +FLAGS += $(INCLUDE) +FLAGS += -MMD + +CXXFLAGS = $(FLAGS) +CXXFLAGS += $(OPTIMIZER) +CXXFLAGS += -std=c++11 +CXXFLAGS += -fno-exceptions +CXXFLAGS += -fno-rtti + +CXXFLAGS += -Wall -Wextra +CXXFLAGS += -Wctor-dtor-privacy +CXXFLAGS += -Wcast-align -Wpointer-arith -Wredundant-decls +CXXFLAGS += -Wshadow -Wcast-qual -Wcast-align -pedantic + +# Produce debugging information (for use with gdb) +#OPTIMIZER = -Og +#FLAGS += -g + +# Use LLVM +#CXX = $(CROSS)clang++ +#CXXFLAGS += -stdlib=libc++ +#LDFLAGS += -lc++ + + +.PHONY: all clean + +all: $(EXE) + +%: %.cpp + $(CXX) $(CXXFLAGS) -o $@ $< + $(SIZE) $@ + +clean: + $(RM) *.d + $(RM) $(EXE) + + +-include $(DEPENDS) diff --git a/device/gxx-linux/tinyfsm-master/examples/api/debugging_switch b/device/gxx-linux/tinyfsm-master/examples/api/debugging_switch new file mode 100644 index 0000000..8573437 Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/api/debugging_switch differ diff --git a/device/gxx-linux/tinyfsm-master/examples/api/debugging_switch.cpp b/device/gxx-linux/tinyfsm-master/examples/api/debugging_switch.cpp new file mode 100644 index 0000000..065d0e1 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/debugging_switch.cpp @@ -0,0 +1,122 @@ +#include +#include +#include + +struct Off; // forward declaration + + +// ---------------------------------------------------------------------------- +// Event Declarations +// +struct Toggle : tinyfsm::Event { }; // Event Declarations + + +// ---------------------------------------------------------------------------- +// State Machine Declaration +// +struct Switch +: tinyfsm::Fsm +{ + static void reset(void); + + // NOTE: on reset: "tinyfsm::StateList::reset()", copy + // constructor is used by default, so "this" points to neither + // "Off" nor "On" (see operator=() below). + Switch() : counter(0) { + std::cout << "* Switch()" << std::endl + << " this = " << this << std::endl; + } + + ~Switch() { + std::cout << "* ~Switch()" << std::endl + << " this = " << this << std::endl; + } + + Switch & operator=(const Switch & other) { + std::cout << "* operator=()" << std::endl + << " this = " << this << std::endl + << " other = " << &other << std::endl; + counter = other.counter; + return *this; + } + + virtual void react(Toggle const &) { }; + void entry(void); + void exit(void); + + int counter; +}; + +struct On : Switch { + void react(Toggle const &) override { transit(); }; +}; + +struct Off : Switch { + void react(Toggle const &) override { transit(); }; +}; + +FSM_INITIAL_STATE(Switch, Off) + + +// ---------------------------------------------------------------------------- +// State Machine Definitions +// +void Switch::reset() { + tinyfsm::StateList::reset(); +} + +void Switch::entry() { + counter++; + + // debugging only. properly designed state machines don't need this: + if(is_in_state()) { std::cout << "* On::entry()" << std::endl; } + else if(is_in_state()) { std::cout << "* Off::entry()" << std::endl; } + else assert(true); + + assert(current_state_ptr == this); + std::cout << " this (cur) = " << this << std::endl + << " state = " << &state() << std::endl + << " state = " << &state() << std::endl; +} + +void Switch::exit() { + assert(current_state_ptr == this); + std::cout << "* exit()" << std::endl + << " this (cur) = " << this << std::endl + << " state = " << &state() << std::endl + << " state = " << &state() << std::endl; +} + + +// ---------------------------------------------------------------------------- +// Main +// +int main() +{ + Switch::start(); + + while(1) + { + char c; + std::cout << "* main()" << std::endl + << " cur_counter = " << Switch::current_state_ptr->counter << std::endl + << " on_counter = " << Switch::state().counter << std::endl + << " off_counter = " << Switch::state().counter << std::endl; + + std::cout << std::endl << "t=Toggle, r=Restart, q=Quit ? "; + std::cin >> c; + switch(c) { + case 't': + Switch::dispatch(Toggle()); + break; + case 'r': + Switch::reset(); + Switch::start(); + break; + case 'q': + return 0; + default: + std::cout << "> Invalid input" << std::endl; + }; + } +} diff --git a/device/gxx-linux/tinyfsm-master/examples/api/debugging_switch.d b/device/gxx-linux/tinyfsm-master/examples/api/debugging_switch.d new file mode 100644 index 0000000..8c573ee --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/debugging_switch.d @@ -0,0 +1 @@ +debugging_switch: debugging_switch.cpp ../../include/tinyfsm.hpp diff --git a/device/gxx-linux/tinyfsm-master/examples/api/mealy_machine b/device/gxx-linux/tinyfsm-master/examples/api/mealy_machine new file mode 100644 index 0000000..94c58a6 Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/api/mealy_machine differ diff --git a/device/gxx-linux/tinyfsm-master/examples/api/mealy_machine.cpp b/device/gxx-linux/tinyfsm-master/examples/api/mealy_machine.cpp new file mode 100644 index 0000000..a4fadff --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/mealy_machine.cpp @@ -0,0 +1,70 @@ +#include +#include + +// ---------------------------------------------------------------------------- +// 1. Event Declarations +// +struct Toggle : tinyfsm::Event { }; + + +// ---------------------------------------------------------------------------- +// 2. State Machine Base Class Declaration +// +struct Switch : tinyfsm::MealyMachine +{ + /* pure virtual reaction (override required in all states) */ + virtual void react(Toggle const &) = 0; + + /* transition actions */ + static void OpenCircuit() { + std::cout << "* Opening ciruit (light goes OFF)" << std::endl; + } + static void CloseCircuit() { + std::cout << "* Closing ciruit (light goes ON)" << std::endl; + } +}; + + +// ---------------------------------------------------------------------------- +// 3. State Declarations +// +struct Off; // forward declaration + +struct On : Switch +{ + void react(Toggle const &) override { transit(OpenCircuit); }; +}; + +struct Off : Switch +{ + void react(Toggle const &) override { transit(CloseCircuit); }; +}; + +FSM_INITIAL_STATE(Switch, Off) + + +// ---------------------------------------------------------------------------- +// Main +// +int main() +{ + Switch::start(); + + std::cout << "> You are facing a light switch..." << std::endl; + while(1) + { + char c; + std::cout << std::endl << "t=Toggle, q=Quit ? "; + std::cin >> c; + switch(c) { + case 't': + std::cout << "> Toggling switch..." << std::endl; + Switch::dispatch(Toggle()); + break; + case 'q': + return 0; + default: + std::cout << "> Invalid input" << std::endl; + }; + } +} diff --git a/device/gxx-linux/tinyfsm-master/examples/api/mealy_machine.d b/device/gxx-linux/tinyfsm-master/examples/api/mealy_machine.d new file mode 100644 index 0000000..c533fc6 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/mealy_machine.d @@ -0,0 +1 @@ +mealy_machine: mealy_machine.cpp ../../include/tinyfsm.hpp diff --git a/device/gxx-linux/tinyfsm-master/examples/api/moore_machine b/device/gxx-linux/tinyfsm-master/examples/api/moore_machine new file mode 100644 index 0000000..9521313 Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/api/moore_machine differ diff --git a/device/gxx-linux/tinyfsm-master/examples/api/moore_machine.cpp b/device/gxx-linux/tinyfsm-master/examples/api/moore_machine.cpp new file mode 100644 index 0000000..02a77da --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/moore_machine.cpp @@ -0,0 +1,64 @@ +#include +#include + +// ---------------------------------------------------------------------------- +// 1. Event Declarations +// +struct Toggle : tinyfsm::Event { }; + + +// ---------------------------------------------------------------------------- +// 2. State Machine Base Class Declaration +// +struct Switch : tinyfsm::MooreMachine +{ + /* pure virtual reaction (override required in all states) */ + virtual void react(Toggle const &) = 0; +}; + + +// ---------------------------------------------------------------------------- +// 3. State Declarations +// +struct Off; // forward declaration + +struct On : Switch +{ + void entry() override { std::cout << "* Closing ciruit (light goes ON)" << std::endl; }; + void react(Toggle const &) override { transit(); }; +}; + +struct Off : Switch +{ + void entry() override { std::cout << "* Opening ciruit (light goes OFF)" << std::endl; }; + void react(Toggle const &) override { transit(); }; +}; + +FSM_INITIAL_STATE(Switch, Off) + + +// ---------------------------------------------------------------------------- +// Main +// +int main() +{ + Switch::start(); + + std::cout << "> You are facing a light switch..." << std::endl; + while(1) + { + char c; + std::cout << std::endl << "t=Toggle, q=Quit ? "; + std::cin >> c; + switch(c) { + case 't': + std::cout << "> Toggling switch..." << std::endl; + Switch::dispatch(Toggle()); + break; + case 'q': + return 0; + default: + std::cout << "> Invalid input" << std::endl; + }; + } +} diff --git a/device/gxx-linux/tinyfsm-master/examples/api/moore_machine.d b/device/gxx-linux/tinyfsm-master/examples/api/moore_machine.d new file mode 100644 index 0000000..8c83e9b --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/moore_machine.d @@ -0,0 +1 @@ +moore_machine: moore_machine.cpp ../../include/tinyfsm.hpp diff --git a/device/gxx-linux/tinyfsm-master/examples/api/multiple_switch b/device/gxx-linux/tinyfsm-master/examples/api/multiple_switch new file mode 100644 index 0000000..de41083 Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/api/multiple_switch differ diff --git a/device/gxx-linux/tinyfsm-master/examples/api/multiple_switch.cpp b/device/gxx-linux/tinyfsm-master/examples/api/multiple_switch.cpp new file mode 100644 index 0000000..6bf844f --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/multiple_switch.cpp @@ -0,0 +1,145 @@ +// +// In this example, we want to use the DefectiveSwitch FSM multiple +// times. As TinyFSM is all about templates, we need to declare it as +// a template class. +// +// This is a bit cumbersome, as the C++ syntax is really ugly when it +// comes to derived template classes. +// +#include +#include +#include /* rand */ + +template +class Off; // forward declaration + +static void DumpState(int inum, const char * state, int on_counter, int defect_level) { + std::cout << "* Switch[" << inum << "] is " << state << " (on_counter=" << on_counter << ", defect_level=" << defect_level << ")" << std::endl; +} + +// ---------------------------------------------------------------------------- +// 1. Event Declarations +// +struct Toggle : tinyfsm::Event { }; + + +// ---------------------------------------------------------------------------- +// 2. State Machine Base Class Declaration +// +template +class DefectiveSwitch +: public tinyfsm::Fsm< DefectiveSwitch > +{ +public: + static constexpr unsigned int defect_level = (inum * 2); + + static void reset(void) { + on_counter = 0; + } + + /* default reaction for unhandled events */ + void react(tinyfsm::Event const &) { }; + + virtual void react(Toggle const &) { }; + virtual void entry(void) { }; /* entry actions in some states */ + void exit(void) { }; /* no exit actions */ + +protected: + static unsigned int on_counter; +}; + +// state variable definitions +template +unsigned int DefectiveSwitch::on_counter{0}; + + +// ---------------------------------------------------------------------------- +// 3. State Declarations +// +template +class On +: public DefectiveSwitch +{ + // note: base class is not known in dependend template + using base = DefectiveSwitch; + void entry() override { + base::on_counter++; + DumpState(inum, "ON ", base::on_counter, base::defect_level); + }; + void react(Toggle const &) override { + base::template transit< Off >(); + }; +}; + + +template +class Off +: public DefectiveSwitch +{ + using base = DefectiveSwitch; + void entry() override { + DumpState(inum, "OFF", base::on_counter, base::defect_level); + }; + void react(Toggle const &) override { + if((rand() % (base::defect_level + 1)) == 0) + base::template transit< On >(); + else { + std::cout << "* Kzzz kzzzzzz" << std::endl; + base::template transit< Off >(); + } + }; +}; + +FSM_INITIAL_STATE(DefectiveSwitch<0>, Off<0> ) +FSM_INITIAL_STATE(DefectiveSwitch<1>, Off<1> ) +FSM_INITIAL_STATE(DefectiveSwitch<2>, Off<2> ) + + +// ---------------------------------------------------------------------------- +// 4. State Machine List Declaration +// + +using fsm_handle = tinyfsm::FsmList< + DefectiveSwitch<0>, + DefectiveSwitch<1>, + DefectiveSwitch<2> + >; + +template +void ToggleSingle() { + std::cout << "> Toggling switch " << inum << "..." << std::endl; + DefectiveSwitch::dispatch(Toggle()); +} + + +// ---------------------------------------------------------------------------- +// Main +// +int main() +{ + fsm_handle::start(); + + while(1) + { + char c; + std::cout << std::endl << "0,1,2=Toggle single, a=Toggle all, r=Restart, q=Quit ? "; + std::cin >> c; + switch(c) { + case '0': ToggleSingle<0>(); break; + case '1': ToggleSingle<1>(); break; + case '2': ToggleSingle<2>(); break; + case 'a': + std::cout << "> Toggling all switches..." << std::endl; + fsm_handle::dispatch(Toggle()); + break; + case 'r': + fsm_handle::reset(); + fsm_handle::start(); + break; + case 'q': + return 0; + default: + std::cout << "> Invalid input" << std::endl; + }; + } +} diff --git a/device/gxx-linux/tinyfsm-master/examples/api/multiple_switch.d b/device/gxx-linux/tinyfsm-master/examples/api/multiple_switch.d new file mode 100644 index 0000000..50c1541 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/multiple_switch.d @@ -0,0 +1 @@ +multiple_switch: multiple_switch.cpp ../../include/tinyfsm.hpp diff --git a/device/gxx-linux/tinyfsm-master/examples/api/resetting_switch b/device/gxx-linux/tinyfsm-master/examples/api/resetting_switch new file mode 100644 index 0000000..fcef791 Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/api/resetting_switch differ diff --git a/device/gxx-linux/tinyfsm-master/examples/api/resetting_switch.cpp b/device/gxx-linux/tinyfsm-master/examples/api/resetting_switch.cpp new file mode 100644 index 0000000..5642fc9 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/resetting_switch.cpp @@ -0,0 +1,110 @@ +#include +#include + +class Off; // forward declaration + + +// ---------------------------------------------------------------------------- +// 1. Event Declarations +// +struct Toggle : tinyfsm::Event { }; + + +// ---------------------------------------------------------------------------- +// 2. State Machine Base Class Declaration +// +class Switch +: public tinyfsm::Fsm +{ + // entry(), exit() and react() are called from Fsm::transit() + // in derived states, make friends: + friend class tinyfsm::Fsm; + + /* default reaction for unhandled events */ + void react(tinyfsm::Event const &) { }; + + virtual void react(Toggle const &) { }; + virtual void entry(void) { }; /* entry actions in some states */ + void exit(void) { }; /* no exit actions */ + +public: + static void reset(void); /* implemented below */ +}; + + +// ---------------------------------------------------------------------------- +// 3. State Declarations +// +class On +: public Switch +{ + void entry() override { counter++; std::cout << "* Switch is ON, counter=" << counter << std::endl; }; + void react(Toggle const &) override { transit(); }; + int counter; + +public: + On() : counter(0) { std::cout << "** RESET State=On" << std::endl; } +}; + +class Off +: public Switch +{ + void entry() override { counter++; std::cout << "* Switch is OFF, counter=" << counter << std::endl; }; + void react(Toggle const &) override { transit(); }; + int counter; + +public: + Off() : counter(0) { std::cout << "** RESET State=Off" << std::endl; } +}; + + +void Switch::reset() { + std::cout << "** RESET Switch" << std::endl; + // Reset all states (calls constructor on all states in list) + tinyfsm::StateList::reset(); + + // Alternatively, make counter public above and reset the values + // here instead of using a copy-constructor with StateList<>: + //state().counter = 0; + //state().counter = 0; +} + +FSM_INITIAL_STATE(Switch, Off) + + +// ---------------------------------------------------------------------------- +// 4. State Machine List Declaration (dispatches events to multiple FSM's) +// +// In this example, we only have a single state machine, no need to use FsmList<>: +//using fsm_handle = tinyfsm::FsmList< Switch >; +using fsm_handle = Switch; + + +// ---------------------------------------------------------------------------- +// Main +// +int main() +{ + fsm_handle::start(); + + while(1) + { + char c; + std::cout << std::endl << "t=Toggle, r=Restart, q=Quit ? "; + std::cin >> c; + switch(c) { + case 't': + std::cout << "> Toggling switch..." << std::endl; + fsm_handle::dispatch(Toggle()); + break; + case 'r': + fsm_handle::reset(); + fsm_handle::start(); + break; + case 'q': + return 0; + default: + std::cout << "> Invalid input" << std::endl; + }; + } +} diff --git a/device/gxx-linux/tinyfsm-master/examples/api/resetting_switch.d b/device/gxx-linux/tinyfsm-master/examples/api/resetting_switch.d new file mode 100644 index 0000000..5d9991f --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/resetting_switch.d @@ -0,0 +1 @@ +resetting_switch: resetting_switch.cpp ../../include/tinyfsm.hpp diff --git a/device/gxx-linux/tinyfsm-master/examples/api/simple_switch b/device/gxx-linux/tinyfsm-master/examples/api/simple_switch new file mode 100644 index 0000000..ad497be Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/api/simple_switch differ diff --git a/device/gxx-linux/tinyfsm-master/examples/api/simple_switch.cpp b/device/gxx-linux/tinyfsm-master/examples/api/simple_switch.cpp new file mode 100644 index 0000000..b20b2ab --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/simple_switch.cpp @@ -0,0 +1,85 @@ +#include +#include + +struct Off; // forward declaration + + +// ---------------------------------------------------------------------------- +// 1. Event Declarations +// +struct Toggle : tinyfsm::Event { }; + + +// ---------------------------------------------------------------------------- +// 2. State Machine Base Class Declaration +// +struct Switch : tinyfsm::Fsm +{ + virtual void react(Toggle const &) { }; + + // alternative: enforce handling of Toggle in all states (pure virtual) + //virtual void react(Toggle const &) = 0; + + virtual void entry(void) { }; /* entry actions in some states */ + void exit(void) { }; /* no exit actions */ + + // alternative: enforce entry actions in all states (pure virtual) + //virtual void entry(void) = 0; +}; + + +// ---------------------------------------------------------------------------- +// 3. State Declarations +// +struct On : Switch +{ + void entry() override { std::cout << "* Switch is ON" << std::endl; }; + void react(Toggle const &) override { transit(); }; +}; + +struct Off : Switch +{ + void entry() override { std::cout << "* Switch is OFF" << std::endl; }; + void react(Toggle const &) override { transit(); }; +}; + +FSM_INITIAL_STATE(Switch, Off) + + +// ---------------------------------------------------------------------------- +// 4. State Machine List Declaration (dispatches events to multiple FSM's) +// +// In this example, we only have a single state machine, no need to use FsmList<>: +//using fsm_handle = tinyfsm::FsmList< Switch >; +using fsm_handle = Switch; + + +// ---------------------------------------------------------------------------- +// Main +// +int main() +{ + // instantiate events + Toggle toggle; + + fsm_handle::start(); + + while(1) + { + char c; + std::cout << std::endl << "t=Toggle, q=Quit ? "; + std::cin >> c; + switch(c) { + case 't': + std::cout << "> Toggling switch..." << std::endl; + fsm_handle::dispatch(toggle); + // alternative: instantiating causes no overhead (empty declaration) + //fsm_handle::dispatch(Toggle()); + break; + case 'q': + return 0; + default: + std::cout << "> Invalid input" << std::endl; + }; + } +} diff --git a/device/gxx-linux/tinyfsm-master/examples/api/simple_switch.d b/device/gxx-linux/tinyfsm-master/examples/api/simple_switch.d new file mode 100644 index 0000000..5d32110 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/api/simple_switch.d @@ -0,0 +1 @@ +simple_switch: simple_switch.cpp ../../include/tinyfsm.hpp diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/Makefile b/device/gxx-linux/tinyfsm-master/examples/elevator/Makefile new file mode 100644 index 0000000..4c97905 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/Makefile @@ -0,0 +1,98 @@ +# Compiler prefix, in case your default compiler does not implement all C++11 features: +#CROSS = /opt/toolchain/x86_64-pc-linux-gnu-gcc-4.7.0/bin/x86_64-pc-linux-gnu- + +PROJECT = elevator + +# HINT: g++ -Q -O2 --help=optimizers +OPTIMIZER = -Os + +CC = $(CROSS)gcc +CXX = $(CROSS)g++ +AS = $(CROSS)gcc -x assembler-with-cpp +LD = $(CROSS)g++ +OBJCOPY = $(CROSS)objcopy +OBJDUMP = $(CROSS)objdump +SIZE = size -d +RM = rm -f +RM_R = rm -rf +CP = cp +MKDIR_P = mkdir -p +DOXYGEN = doxygen + + +SRC_DIRS = . +INCLUDE = -I ../../include + +SRCS = $(wildcard $(addsuffix /*.cpp, $(SRC_DIRS))) +OBJS = $(SRCS:.cpp=.o) +DEPENDS = $(OBJS:.o=.d) + +EXE = $(PROJECT) +MAP = $(PROJECT).map + + +#------------------------------------------------------------------------------ +# flags +# + +# commmon flags propagated to CFLAGS, CXXFLAGS, ASFLAGS (not LDFLAGS) +FLAGS += $(INCLUDE) +FLAGS += -MMD + +CXXFLAGS = $(FLAGS) +CXXFLAGS += $(OPTIMIZER) +CXXFLAGS += -std=c++11 +CXXFLAGS += -fno-exceptions +CXXFLAGS += -fno-rtti + +CXXFLAGS += -Wall -Wextra +CXXFLAGS += -Wctor-dtor-privacy +CXXFLAGS += -Wcast-align -Wpointer-arith -Wredundant-decls +CXXFLAGS += -Wshadow -Wcast-qual -Wcast-align -pedantic + +LDFLAGS += -fno-exceptions +LDFLAGS += -fno-rtti + +# Produce debugging information (for use with gdb) +#OPTIMIZER = -Og +#FLAGS += -g + +# Use LLVM +#CXX = $(CROSS)clang++ +#CXXFLAGS += -stdlib=libc++ +#LDFLAGS += -lc++ + +# Enable link-time optimizer +#CXXFLAGS += -flto +#LDFLAGS += -flto + +# Strip dead code (enable garbage collection) +#OPTIMIZER += -ffunction-sections -fdata-sections +#LDFLAGS += -Wl,$(if $(shell ld -v | grep GNU),--gc-sections,-dead_strip) + +# Enable automatic template instantiation at link time +#CXXFLAGS += -frepo +#LDFLAGS += -frepo + +# Create link map file +#LDFLAGS += -Wl,-Map="$(MAP)",--cref + + +.PHONY: all clean + +all: $(EXE) + +$(EXE): $(OBJS) + $(LD) $(OBJS) $(LDFLAGS) -o $(EXE) + $(SIZE) $@ + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) -o $@ $< + +clean: + $(RM) *.o + $(RM) *.d + $(RM) $(EXE) + + +-include $(DEPENDS) diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/README.md b/device/gxx-linux/tinyfsm-master/examples/elevator/README.md new file mode 100644 index 0000000..71d5c93 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/README.md @@ -0,0 +1,88 @@ +Elevator Project +================ + +Example implementation of a simplified elevator logic, using [TinyFSM]. + + [TinyFSM]: https://digint.ch/tinyfsm/ + + +Overview +-------- + +Imagine a elevator having: + + - "Call" button on each floor, + - "Floor Sensor" on each floor, triggering an event as soon as the + elevator arrives there, + - "Alarm" button. + + +Implementation +-------------- + +The elevator example implements two state machines interacting with +each other: + + 1. Elevator + - State: Idle + - State: Moving + - State: Panic + + 2. Motor + - State: Stopped + - State: Up + - State: Down + + +[insert ascii-art here] + +A good state machine design avoids circular dependencies at all +cost: While the elevator sends events to the motor, the motor NEVER +sends events to the elevator (top-down only). + + +FAQ +--- + +Did you notice the motor starting twice? This is by design, let's +have a look at the call stack of fsm_list::start() in main.cpp: + + FsmList::start() + Motor::set_initial_state() + Motor::current_state = Stopped + Elevator::set_initial_state() + Elevator::current_state = Idle + Motor::enter() + Motor:Stopped->entry() + cout << "Motor: stopped" <-- HERE + Motor::direction = 0 + Elevator::enter() + Elevator:Idle->entry() + send_event(MotorStop) + Motor::react(MotorStop) + Motor:Stopped->transit + Motor:Stopped->exit() + Motor::current_state = Stopped + Motor:Stopped->entry() + cout << "Motor: stopped" <-- HERE + Motor::direction = 0 + Elevator::react(MotorStop) + +If we really had to work around this, we could either: + + 1. Change the initialization (bad design practice!) in main.cpp: + + - fsm_list::start(); + + fsm_list::set_initial_state(); + + Elevator::enter(); + + + 2. Modify the Motor:Stopped->entry() function in motor.cpp: + + class Stopped : public Motor { + void entry() override { + + if(direction == 0) + + return; + cout << "Motor: stopped" << endl; + direction = 0; + }; diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/elevator b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator new file mode 100644 index 0000000..7634398 Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator differ diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.cpp b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.cpp new file mode 100644 index 0000000..6e792f6 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.cpp @@ -0,0 +1,115 @@ +#include + +#include "elevator.hpp" +#include "fsmlist.hpp" + +#include + +class Idle; // forward declaration + + +// ---------------------------------------------------------------------------- +// Transition functions +// + +static void CallMaintenance() { + std::cout << "*** calling maintenance ***" << std::endl; +} + +static void CallFirefighters() { + std::cout << "*** calling firefighters ***" << std::endl; +} + + +// ---------------------------------------------------------------------------- +// State: Panic +// + +class Panic +: public Elevator +{ + void entry() override { + send_event(MotorStop()); + } +}; + + +// ---------------------------------------------------------------------------- +// State: Moving +// + +class Moving +: public Elevator +{ + void react(FloorSensor const & e) override { + int floor_expected = current_floor + Motor::getDirection(); + if(floor_expected != e.floor) + { + std::cout << "Floor sensor defect (expected " << floor_expected << ", got " << e.floor << ")" << std::endl; + transit(CallMaintenance); + } + else + { + std::cout << "Reached floor " << e.floor << std::endl; + current_floor = e.floor; + if(e.floor == dest_floor) + transit(); + } + }; +}; + + +// ---------------------------------------------------------------------------- +// State: Idle +// + +class Idle +: public Elevator +{ + void entry() override { + send_event(MotorStop()); + } + + void react(Call const & e) override { + dest_floor = e.floor; + + if(dest_floor == current_floor) + return; + + /* lambda function used for transition action */ + auto action = [] { + if(dest_floor > current_floor) + send_event(MotorUp()); + else if(dest_floor < current_floor) + send_event(MotorDown()); + }; + + transit(action); + }; +}; + + +// ---------------------------------------------------------------------------- +// Base state: default implementations +// + +void Elevator::react(Call const &) { + std::cout << "Call event ignored" << std::endl; +} + +void Elevator::react(FloorSensor const &) { + std::cout << "FloorSensor event ignored" << std::endl; +} + +void Elevator::react(Alarm const &) { + transit(CallFirefighters); +} + +int Elevator::current_floor = Elevator::initial_floor; +int Elevator::dest_floor = Elevator::initial_floor; + + +// ---------------------------------------------------------------------------- +// Initial state definition +// +FSM_INITIAL_STATE(Elevator, Idle) diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.d b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.d new file mode 100644 index 0000000..873085f --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.d @@ -0,0 +1,2 @@ +elevator.o: elevator.cpp ../../include/tinyfsm.hpp elevator.hpp \ + fsmlist.hpp motor.hpp diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.hpp b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.hpp new file mode 100644 index 0000000..be3d005 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.hpp @@ -0,0 +1,55 @@ +#ifndef ELEVATOR_HPP_INCLUDED +#define ELEVATOR_HPP_INCLUDED + +#include + + +// ---------------------------------------------------------------------------- +// Event declarations +// + +struct FloorEvent : tinyfsm::Event +{ + int floor; +}; + +struct Call : FloorEvent { }; +struct FloorSensor : FloorEvent { }; +struct Alarm : tinyfsm::Event { }; + + + +// ---------------------------------------------------------------------------- +// Elevator (FSM base class) declaration +// + +class Elevator +: public tinyfsm::Fsm +{ + /* NOTE: react(), entry() and exit() functions need to be accessible + * from tinyfsm::Fsm class. You might as well declare friendship to + * tinyfsm::Fsm, and make these functions private: + * + * friend class Fsm; + */ +public: + + /* default reaction for unhandled events */ + void react(tinyfsm::Event const &) { }; + + virtual void react(Call const &); + virtual void react(FloorSensor const &); + void react(Alarm const &); + + virtual void entry(void) { }; /* entry actions in some states */ + void exit(void) { }; /* no exit actions at all */ + +protected: + + static constexpr int initial_floor = 0; + static int current_floor; + static int dest_floor; +}; + + +#endif diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.o b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.o new file mode 100644 index 0000000..710d28d Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/elevator/elevator.o differ diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/fsmlist.hpp b/device/gxx-linux/tinyfsm-master/examples/elevator/fsmlist.hpp new file mode 100644 index 0000000..d340f8a --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/fsmlist.hpp @@ -0,0 +1,19 @@ +#ifndef FSMLIST_HPP_INCLUDED +#define FSMLIST_HPP_INCLUDED + +#include + +#include "elevator.hpp" +#include "motor.hpp" + +using fsm_list = tinyfsm::FsmList; + +/** dispatch event to both "Motor" and "Elevator" */ +template +void send_event(E const & event) +{ + fsm_list::template dispatch(event); +} + + +#endif diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/main.cpp b/device/gxx-linux/tinyfsm-master/examples/elevator/main.cpp new file mode 100644 index 0000000..4657015 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/main.cpp @@ -0,0 +1,40 @@ +#include "fsmlist.hpp" + +#include + + +int main() +{ + fsm_list::start(); + + Call call; + FloorSensor sensor; + + while(1) + { + char c; + + std::cout << "c=Call, f=FloorSensor, a=Alarm, q=Quit ? "; + std::cin >> c; + switch(c) { + case 'c': + std::cout << "Floor ? "; + std::cin >> call.floor; + send_event(call); + break; + case 'f': + std::cout << "Floor ? "; + std::cin >> sensor.floor; + send_event(sensor); + break; + case 'a': + send_event(Alarm()); + break; + case 'q': + std::cout << "Thanks for playing!" << std::endl; + return 0; + default: + std::cout << "Invalid input" << std::endl; + }; + } +} diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/main.d b/device/gxx-linux/tinyfsm-master/examples/elevator/main.d new file mode 100644 index 0000000..a8fba41 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/main.d @@ -0,0 +1,2 @@ +main.o: main.cpp fsmlist.hpp ../../include/tinyfsm.hpp elevator.hpp \ + motor.hpp diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/main.o b/device/gxx-linux/tinyfsm-master/examples/elevator/main.o new file mode 100644 index 0000000..9985e07 Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/elevator/main.o differ diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/motor.cpp b/device/gxx-linux/tinyfsm-master/examples/elevator/motor.cpp new file mode 100644 index 0000000..b466807 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/motor.cpp @@ -0,0 +1,60 @@ +#include +#include "motor.hpp" +#include + + +// ---------------------------------------------------------------------------- +// Motor states +// + +class Stopped +: public Motor +{ + void entry() override { + std::cout << "Motor: stopped" << std::endl; + direction = 0; + }; +}; + +class Up +: public Motor +{ + void entry() override { + std::cout << "Motor: moving up" << std::endl; + direction = 1; + }; +}; + +class Down +: public Motor +{ + void entry() override { + std::cout << "Motor: moving down" << std::endl; + direction = -1; + }; +}; + + +// ---------------------------------------------------------------------------- +// Base State: default implementations +// + +void Motor::react(MotorStop const &) { + transit(); +} + +void Motor::react(MotorUp const &) { + transit(); +} + +void Motor::react(MotorDown const &) { + transit(); +} + +int Motor::direction{0}; + + +// ---------------------------------------------------------------------------- +// Initial state definition +// +FSM_INITIAL_STATE(Motor, Stopped) diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/motor.d b/device/gxx-linux/tinyfsm-master/examples/elevator/motor.d new file mode 100644 index 0000000..02e7e75 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/motor.d @@ -0,0 +1 @@ +motor.o: motor.cpp ../../include/tinyfsm.hpp motor.hpp diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/motor.hpp b/device/gxx-linux/tinyfsm-master/examples/elevator/motor.hpp new file mode 100644 index 0000000..7d2447c --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/examples/elevator/motor.hpp @@ -0,0 +1,50 @@ +#ifndef MOTOR_HPP_INCLUDED +#define MOTOR_HPP_INCLUDED + +#include + + +// ---------------------------------------------------------------------------- +// Event declarations +// + +struct MotorUp : tinyfsm::Event { }; +struct MotorDown : tinyfsm::Event { }; +struct MotorStop : tinyfsm::Event { }; + + +// ---------------------------------------------------------------------------- +// Motor (FSM base class) declaration +// +class Motor +: public tinyfsm::Fsm +{ + /* NOTE: react(), entry() and exit() functions need to be accessible + * from tinyfsm::Fsm class. You might as well declare friendship to + * tinyfsm::Fsm, and make these functions private: + * + * friend class Fsm; + */ +public: + + /* default reaction for unhandled events */ + void react(tinyfsm::Event const &) { }; + + /* non-virtual declaration: reactions are the same for all states */ + void react(MotorUp const &); + void react(MotorDown const &); + void react(MotorStop const &); + + virtual void entry(void) = 0; /* pure virtual: enforce implementation in all states */ + void exit(void) { }; /* no exit actions at all */ + +protected: + + static int direction; + +public: + static int getDirection() { return direction; } +}; + + +#endif diff --git a/device/gxx-linux/tinyfsm-master/examples/elevator/motor.o b/device/gxx-linux/tinyfsm-master/examples/elevator/motor.o new file mode 100644 index 0000000..415a020 Binary files /dev/null and b/device/gxx-linux/tinyfsm-master/examples/elevator/motor.o differ diff --git a/device/gxx-linux/tinyfsm-master/include/tinyfsm.hpp b/device/gxx-linux/tinyfsm-master/include/tinyfsm.hpp new file mode 100644 index 0000000..075251d --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/include/tinyfsm.hpp @@ -0,0 +1,252 @@ +/* + * TinyFSM - Tiny Finite State Machine Processor + * + * Copyright (c) 2012-2018 Axel Burri + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* --------------------------------------------------------------------- + * Version: 0.3.2 + * + * API documentation: see "../doc/50-API.md" + * + * The official TinyFSM website is located at: + * https://digint.ch/tinyfsm/ + * + * Author: + * Axel Burri + * --------------------------------------------------------------------- + */ + +#ifndef TINYFSM_HPP_INCLUDED +#define TINYFSM_HPP_INCLUDED + +#ifndef TINYFSM_NOSTDLIB +#include +#endif + +// #include +// #define DBG(str) do { std::cerr << str << std::endl; } while( false ) +// DBG("*** dbg_example *** " << __PRETTY_FUNCTION__); + +namespace tinyfsm +{ + + // -------------------------------------------------------------------------- + + struct Event { }; + + // -------------------------------------------------------------------------- + +#ifdef TINYFSM_NOSTDLIB + // remove dependency on standard library (silent fail!). + // useful in conjunction with -nostdlib option, e.g. if your compiler + // does not provide a standard library. + // NOTE: this silently disables all static_assert() calls below! + template + struct is_same_fsm { static constexpr bool value = true; }; +#else + // check if both fsm and state class share same fsmtype + template + struct is_same_fsm : std::is_same< typename F::fsmtype, typename S::fsmtype > { }; +#endif + + template + struct _state_instance + { + using value_type = S; + using type = _state_instance; + static S value; + }; + + template + typename _state_instance::value_type _state_instance::value; + + // -------------------------------------------------------------------------- + + template + class Fsm + { + public: + + using fsmtype = Fsm; + using state_ptr_t = F *; + + static state_ptr_t current_state_ptr; + + // public, leaving ability to access state instance (e.g. on reset) + template + static constexpr S & state(void) { + static_assert(is_same_fsm::value, "accessing state of different state machine"); + return _state_instance::value; + } + + template + static constexpr bool is_in_state(void) { + static_assert(is_same_fsm::value, "accessing state of different state machine"); + return current_state_ptr == &_state_instance::value; + } + + /// state machine functions + public: + + // explicitely specialized in FSM_INITIAL_STATE macro + static void set_initial_state(); + + static void reset() { }; + + static void enter() { + current_state_ptr->entry(); + } + + static void start() { + set_initial_state(); + enter(); + } + + template + static void dispatch(E const & event) { + current_state_ptr->react(event); + } + + + /// state transition functions + protected: + + template + void transit(void) { + static_assert(is_same_fsm::value, "transit to different state machine"); + current_state_ptr->exit(); + current_state_ptr = &_state_instance::value; + current_state_ptr->entry(); + } + + template + void transit(ActionFunction action_function) { + static_assert(is_same_fsm::value, "transit to different state machine"); + current_state_ptr->exit(); + // NOTE: we get into deep trouble if the action_function sends a new event. + // TODO: implement a mechanism to check for reentrancy + action_function(); + current_state_ptr = &_state_instance::value; + current_state_ptr->entry(); + } + + template + void transit(ActionFunction action_function, ConditionFunction condition_function) { + if(condition_function()) { + transit(action_function); + } + } + }; + + template + typename Fsm::state_ptr_t Fsm::current_state_ptr; + + // -------------------------------------------------------------------------- + + template + struct FsmList; + + template<> struct FsmList<> { + static void set_initial_state() { } + static void reset() { } + static void enter() { } + template + static void dispatch(E const &) { } + }; + + template + struct FsmList + { + using fsmtype = Fsm; + + static void set_initial_state() { + fsmtype::set_initial_state(); + FsmList::set_initial_state(); + } + + static void reset() { + F::reset(); + FsmList::reset(); + } + + static void enter() { + fsmtype::enter(); + FsmList::enter(); + } + + static void start() { + set_initial_state(); + enter(); + } + + template + static void dispatch(E const & event) { + fsmtype::template dispatch(event); + FsmList::template dispatch(event); + } + }; + + // -------------------------------------------------------------------------- + + template struct StateList; + template<> struct StateList<> { + static void reset() { } + }; + template + struct StateList + { + static void reset() { + _state_instance::value = S(); + StateList::reset(); + } + }; + + // -------------------------------------------------------------------------- + + template + struct MooreMachine : tinyfsm::Fsm + { + virtual void entry(void) { }; /* entry actions in some states */ + void exit(void) { }; /* no exit actions */ + }; + + template + struct MealyMachine : tinyfsm::Fsm + { + // input actions are modeled in react(): + // - conditional dependent of event type or payload + // - transit<>(ActionFunction) + void entry(void) { }; /* no entry actions */ + void exit(void) { }; /* no exit actions */ + }; + +} /* namespace tinyfsm */ + + +#define FSM_INITIAL_STATE(_FSM, _STATE) \ +namespace tinyfsm { \ + template<> void Fsm< _FSM >::set_initial_state(void) { \ + current_state_ptr = &_state_instance< _STATE >::value; \ + } \ +} + +#endif /* TINYFSM_HPP_INCLUDED */ diff --git a/device/gxx-linux/tinyfsm-master/library.json b/device/gxx-linux/tinyfsm-master/library.json new file mode 100644 index 0000000..fab83b5 --- /dev/null +++ b/device/gxx-linux/tinyfsm-master/library.json @@ -0,0 +1,24 @@ +{ + "name": "tinyfsm", + "description": "A simple C++ finite state machine library", + "version": "0.3.2", + "repository": { + "type": "git", + "url": "https://dev.tty0.ch/tinyfsm.git" + }, + "homepage": "https://digint.ch/tinyfsm/", + "authors": { + "name": "Axel Burri", + "email": "axel@tty0.ch", + "url": "http://digint.ch", + "maintainer": true + }, + "license": "MIT", + "platforms": "*", + "frameworks": "*", + "build": { + "flags": [ + "-I include/" + ] + } +} diff --git a/device/gxx-linux/testusb/usb-rk3399/src/app.log b/device/gxx-linux/tinyfsm-master/tree.h similarity index 100% rename from device/gxx-linux/testusb/usb-rk3399/src/app.log rename to device/gxx-linux/tinyfsm-master/tree.h diff --git a/device/gxx-linux/usb/inc/usbdevice.h b/device/gxx-linux/usb/inc/usbdevice.h index 8fbd4d2..9baeb2e 100644 --- a/device/gxx-linux/usb/inc/usbdevice.h +++ b/device/gxx-linux/usb/inc/usbdevice.h @@ -1,4 +1,6 @@ + #pragma once + #include #include #include @@ -10,46 +12,25 @@ #include "buildconf.h" #include "usb_gadget.h" -#include "usb_io.h" -#include #include -class UsbDevice #ifdef ASYNC_EP - : public sane_cfg_provider +class async_scanner; #endif + +class UsbDevice { #ifdef ASYNC_EP - async_usb_gadget *usb_; - sane_cfg_mgr *cfg_; - uint32_t img_cnt_; - uint32_t scan_id_; - uint32_t dpi_; - uint32_t scan_cnt_; - uint32_t scan_err_; - std::string cfg_text_; - dyn_mem_ptr scan_over_pack_; - - dyn_mem_ptr unhandled_ep0(struct usb_functionfs_event* pev); - dyn_mem_ptr handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - - std::map dispatcher_; - dyn_mem_ptr handle_packet_heart_beat(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_packet_invalid(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_packet_get_setting(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_packet_set_setting(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - - dyn_mem_ptr handle_packet_write_file(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_packet_read_file(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + async_scanner *ascan_; void do_system_command(const char* cmd); - void init(void); public: - void save_image(MemoryPtr data, bool img); - - 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; + int start_scan(void); + int stop_scan(void); + int set_dpi(int *dpix, int* dpiy); + int set_scan_num(int num); + int set_img_receiver(void* api, void* param); #endif public: diff --git a/device/gxx-linux/usb/src/common/encrypt.cpp b/device/gxx-linux/usb/src/async_model/common/encrypt.cpp similarity index 100% rename from device/gxx-linux/usb/src/common/encrypt.cpp rename to device/gxx-linux/usb/src/async_model/common/encrypt.cpp diff --git a/device/gxx-linux/usb/src/common/encrypt.h b/device/gxx-linux/usb/src/async_model/common/encrypt.h similarity index 98% rename from device/gxx-linux/usb/src/common/encrypt.h rename to device/gxx-linux/usb/src/async_model/common/encrypt.h index 97d427f..5e64b9f 100644 --- a/device/gxx-linux/usb/src/common/encrypt.h +++ b/device/gxx-linux/usb/src/async_model/common/encrypt.h @@ -6,7 +6,7 @@ #include "referer.h" -#include "data.h" +#include "io/data.h" enum encryptor diff --git a/device/gxx-linux/usb/src/common/ipc_util.cpp b/device/gxx-linux/usb/src/async_model/common/ipc_util.cpp similarity index 100% rename from device/gxx-linux/usb/src/common/ipc_util.cpp rename to device/gxx-linux/usb/src/async_model/common/ipc_util.cpp diff --git a/device/gxx-linux/usb/src/common/ipc_util.h b/device/gxx-linux/usb/src/async_model/common/ipc_util.h similarity index 100% rename from device/gxx-linux/usb/src/common/ipc_util.h rename to device/gxx-linux/usb/src/async_model/common/ipc_util.h diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/json/cJSON.c b/device/gxx-linux/usb/src/async_model/common/json/cJSON.c similarity index 97% rename from device/gxx-linux/testusb/usb-rk3399/src/common/json/cJSON.c rename to device/gxx-linux/usb/src/async_model/common/json/cJSON.c index cd60134..594376b 100644 --- a/device/gxx-linux/testusb/usb-rk3399/src/common/json/cJSON.c +++ b/device/gxx-linux/usb/src/async_model/common/json/cJSON.c @@ -776,19 +776,19 @@ cJSON *cJSON_Duplicate(cJSON *item,int recurse) return newitem; } -void cJSON_Minify(char *json) +void cJSON_Minify(char *gb_json) { - char *into=json; - while (*json) + char *into=gb_json; + while (*gb_json) { - if (*json==' ') json++; - else if (*json=='\t') json++; /* Whitespace characters. */ - else if (*json=='\r') json++; - else if (*json=='\n') json++; - else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; /* double-slash comments, to end of line. */ - else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} /* multiline comments. */ - else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} /* string literals, which are \" sensitive. */ - else *into++=*json++; /* All other characters. */ + if (*gb_json==' ') gb_json++; + else if (*gb_json=='\t') gb_json++; /* Whitespace characters. */ + else if (*gb_json=='\r') gb_json++; + else if (*gb_json=='\n') gb_json++; + else if (*gb_json=='/' && gb_json[1]=='/') while (*gb_json && *gb_json!='\n') gb_json++; /* double-slash comments, to end of line. */ + else if (*gb_json=='/' && gb_json[1]=='*') {while (*gb_json && !(*gb_json=='*' && gb_json[1]=='/')) gb_json++;gb_json+=2;} /* multiline comments. */ + else if (*gb_json=='\"'){*into++=*gb_json++;while (*gb_json && *gb_json!='\"'){if (*gb_json=='\\') *into++=*gb_json++;*into++=*gb_json++;}*into++=*gb_json++;} /* string literals, which are \" sensitive. */ + else *into++=*gb_json++; /* All other characters. */ } *into=0; /* and null-terminate. */ } diff --git a/device/gxx-linux/usb/src/common/json/cJSON.h b/device/gxx-linux/usb/src/async_model/common/json/cJSON.h similarity index 99% rename from device/gxx-linux/usb/src/common/json/cJSON.h rename to device/gxx-linux/usb/src/async_model/common/json/cJSON.h index 913bc1e..9fdbf9b 100644 --- a/device/gxx-linux/usb/src/common/json/cJSON.h +++ b/device/gxx-linux/usb/src/async_model/common/json/cJSON.h @@ -133,7 +133,7 @@ The item->next and ->prev pointers are always zero on return from Duplicate. */ /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); -extern void cJSON_Minify(char *json); +extern void cJSON_Minify(char *gb_json); // convert e681a2 to \u6062, call 'free' to free the returned value extern char* cJSON_utf8_2_unic(const char* utf8); diff --git a/device/gxx-linux/usb/src/common/json/json.cpp b/device/gxx-linux/usb/src/async_model/common/json/gb_json.cpp similarity index 72% rename from device/gxx-linux/usb/src/common/json/json.cpp rename to device/gxx-linux/usb/src/async_model/common/json/gb_json.cpp index e3b4b3a..e8610c8 100644 --- a/device/gxx-linux/usb/src/common/json/json.cpp +++ b/device/gxx-linux/usb/src/async_model/common/json/gb_json.cpp @@ -1,5 +1,5 @@ -#include "json.h" +#include "gb_json.h" #include "cJSON.h" #include #include @@ -81,72 +81,72 @@ namespace special_char_trans } -json::json(char* json_txt) : type_(VAL_TYPE_OBJECT), key_(""), strval_(""), cur_child_(-1) +gb_json::gb_json(char* json_txt) : type_(VAL_TYPE_OBJECT), key_(""), strval_(""), cur_child_(-1) { simple_val_.dval = .0f; if(json_txt) attach_text(json_txt); } -json::json(const char* key, bool val) : type_(VAL_TYPE_BOOL), key_(key ? key : ""), strval_(""), cur_child_(-1) +gb_json::gb_json(const char* key, bool val) : type_(VAL_TYPE_BOOL), key_(key ? key : ""), strval_(""), cur_child_(-1) { simple_val_.bval = val; } -json::json(const char* key, int val) : type_(VAL_TYPE_INT), key_(key ? key : ""), strval_(""), cur_child_(-1) +gb_json::gb_json(const char* key, int val) : type_(VAL_TYPE_INT), key_(key ? key : ""), strval_(""), cur_child_(-1) { simple_val_.nval = val; } -json::json(const char* key, double val) : type_(VAL_TYPE_FLOAT), key_(key ? key : ""), strval_(""), cur_child_(-1) +gb_json::gb_json(const char* key, double val) : type_(VAL_TYPE_FLOAT), key_(key ? key : ""), strval_(""), cur_child_(-1) { simple_val_.dval = val; } -json::json(const char* key, const char* val) : type_(VAL_TYPE_STRING), key_(key ? key : ""), strval_(val ? val : ""), cur_child_(-1) +gb_json::gb_json(const char* key, const char* val) : type_(VAL_TYPE_STRING), key_(key ? key : ""), strval_(val ? val : ""), cur_child_(-1) {} -json::~json() +gb_json::~gb_json() { clear(); } -std::string json::object_key(json* jsn) +std::string gb_json::object_key(gb_json* jsn) { return "\"" + jsn->key() + "\":"; } -std::string json::array_key(json* jsn) +std::string gb_json::array_key(gb_json* jsn) { return ""; } -void json::from_cjson(cJSON* cj) +void gb_json::from_cjson(cJSON* cj) { key_ = cj && cj->string ? cj->string : ""; while (cj) { - json* child = nullptr; + gb_json* child = nullptr; if (cj->type == cJSON_True) { - child = new json(cj->string, true); + child = new gb_json(cj->string, true); } else if(cj->type == cJSON_False) { - child = new json(cj->string, false); + child = new gb_json(cj->string, false); } else if (cj->type == cJSON_Number) { if (cj->valuedouble - (int)cj->valuedouble < .00001) { - child = new json(cj->string, cj->valueint); + child = new gb_json(cj->string, cj->valueint); } else { - child = new json(cj->string, cj->valuedouble); + child = new gb_json(cj->string, cj->valuedouble); } } else if (cj->type == cJSON_String) { - child = new json(cj->string, cj->valuestring); + child = new gb_json(cj->string, cj->valuestring); } else if (cj->type == cJSON_Object || cj->type == cJSON_Array) { - child = new json(); + child = new gb_json(); child->from_cjson(cj->child); child->key_ = cj->string ? cj->string : ""; } @@ -156,7 +156,7 @@ void json::from_cjson(cJSON* cj) if (arr_val_.size() == 1 && arr_val_[0]->arr_val_.size() == 0) { - json* child = arr_val_[0]; + gb_json* child = arr_val_[0]; if (!child->key_.empty()) // array { @@ -177,9 +177,9 @@ void json::from_cjson(cJSON* cj) type_ = arr_val_[0]->key().empty() ? VAL_TYPE_ARRAY : VAL_TYPE_OBJECT; } } -json* json::find_child(const char* key, bool remove) +gb_json* gb_json::find_child(const char* key, bool remove) { - json* ret = nullptr; + gb_json* ret = nullptr; if (type_ == VAL_TYPE_OBJECT) { @@ -201,7 +201,7 @@ json* json::find_child(const char* key, bool remove) return ret; } -bool json::attach_text(char* json_txt) +bool gb_json::attach_text(char* json_txt) { clear(); @@ -220,7 +220,7 @@ bool json::attach_text(char* json_txt) return false; } -void json::clear(bool as_array) +void gb_json::clear(bool as_array) { if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) { @@ -234,7 +234,7 @@ void json::clear(bool as_array) arr_val_.clear(); cur_child_ = -1; } -std::string json::to_string(void) +std::string gb_json::to_string(void) { if (type_ == VAL_TYPE_NULL) return ""; @@ -255,7 +255,7 @@ std::string json::to_string(void) return "\"" + r + "\""; } - std::string(*k)(json*) = type_ == VAL_TYPE_OBJECT ? json::object_key : json::array_key; + std::string(*k)(gb_json*) = type_ == VAL_TYPE_OBJECT ? gb_json::object_key : gb_json::array_key; std::string str(type_ == VAL_TYPE_OBJECT ? "{" : "["); if (arr_val_.size()) @@ -269,15 +269,15 @@ std::string json::to_string(void) return str; } -std::string& json::key(void) +std::string& gb_json::key(void) { return key_; } -bool json::is_array(void) +bool gb_json::is_array(void) { return type_ == VAL_TYPE_ARRAY; } -bool json::is_leaf_node(void) +bool gb_json::is_leaf_node(void) { return type_ == VAL_TYPE_BOOL || type_ == VAL_TYPE_INT || @@ -285,10 +285,10 @@ bool json::is_leaf_node(void) type_ == VAL_TYPE_STRING; } -bool json::get_value(const char* key, bool& val) +bool gb_json::get_value(const char* key, bool& val) { bool ret = false; - json* child = find_child(key); + gb_json* child = find_child(key); if (child) { @@ -307,10 +307,10 @@ bool json::get_value(const char* key, bool& val) return ret; } -bool json::get_value(const char* key, int& val) +bool gb_json::get_value(const char* key, int& val) { bool ret = false; - json* child = find_child(key); + gb_json* child = find_child(key); if (child) { @@ -329,10 +329,10 @@ bool json::get_value(const char* key, int& val) return ret; } -bool json::get_value(const char* key, double& val) +bool gb_json::get_value(const char* key, double& val) { bool ret = false; - json* child = find_child(key); + gb_json* child = find_child(key); if (child) { @@ -349,12 +349,21 @@ bool json::get_value(const char* key, double& val) ret = true; } + // added on 2023-04-27: for cJSON consider both int and float as CJSON_Number, we consider int if the value is just an integer + if(!ret) + { + int v = 0; + ret = get_value(key, v); + if(ret) + val = v; + } + return ret; } -bool json::get_value(const char* key, std::string& val) +bool gb_json::get_value(const char* key, std::string& val) { bool ret = false; - json* child = find_child(key); + gb_json* child = find_child(key); if (child) { @@ -373,10 +382,10 @@ bool json::get_value(const char* key, std::string& val) return ret; } -bool json::get_value(const char* key, json*& val) +bool gb_json::get_value(const char* key, gb_json*& val) { bool ret = false; - json *child = find_child(key); + gb_json *child = find_child(key); if (child) { @@ -394,14 +403,14 @@ bool json::get_value(const char* key, json*& val) return ret; } -size_t json::children(void) +size_t gb_json::children(void) { if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) return arr_val_.size(); else return -1; } -json* json::child(size_t ind) +gb_json* gb_json::child(size_t ind) { if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) { @@ -415,7 +424,7 @@ json* json::child(size_t ind) return nullptr; } -json* json::first_child(void) +gb_json* gb_json::first_child(void) { if (type_ == VAL_TYPE_OBJECT || type_ == VAL_TYPE_ARRAY) { @@ -430,7 +439,7 @@ json* json::first_child(void) return nullptr; } -json* json::next_child(void) +gb_json* gb_json::next_child(void) { if (type_ == VAL_TYPE_OBJECT || type_ == VAL_TYPE_ARRAY) { @@ -445,12 +454,12 @@ json* json::next_child(void) return nullptr; } -bool json::set_value(const char* key, bool val) +bool gb_json::set_value(const char* key, bool val) { if (type_ != VAL_TYPE_OBJECT) return false; - json* child = find_child(key); + gb_json* child = find_child(key); if (child) { @@ -462,18 +471,18 @@ bool json::set_value(const char* key, bool val) } else { - child = new json(key, val); + child = new gb_json(key, val); arr_val_.push_back(child); } return true; } -bool json::set_value(const char* key, int val) +bool gb_json::set_value(const char* key, int val) { if (type_ != VAL_TYPE_OBJECT) return false; - json* child = find_child(key); + gb_json* child = find_child(key); if (child) { @@ -485,18 +494,18 @@ bool json::set_value(const char* key, int val) } else { - child = new json(key, val); + child = new gb_json(key, val); arr_val_.push_back(child); } return true; } -bool json::set_value(const char* key, double val) +bool gb_json::set_value(const char* key, double val) { if (type_ != VAL_TYPE_OBJECT) return false; - json* child = find_child(key); + gb_json* child = find_child(key); if (child) { @@ -508,18 +517,18 @@ bool json::set_value(const char* key, double val) } else { - child = new json(key, val); + child = new gb_json(key, val); arr_val_.push_back(child); } return true; } -bool json::set_value(const char* key, const char* val) +bool gb_json::set_value(const char* key, const char* val) { if (type_ != VAL_TYPE_OBJECT) return false; - json* child = find_child(key); + gb_json* child = find_child(key); if (child) { @@ -531,13 +540,13 @@ bool json::set_value(const char* key, const char* val) } else { - child = new json(key, val); + child = new gb_json(key, val); arr_val_.push_back(child); } return true; } -bool json::set_value(const char* key, json* val) +bool gb_json::set_value(const char* key, gb_json* val) { if (type_ != VAL_TYPE_OBJECT) return false; @@ -560,47 +569,47 @@ bool json::set_value(const char* key, json* val) return true; } -json& json::operator+=(bool val) +gb_json& gb_json::operator+=(bool val) { if (type_ == VAL_TYPE_ARRAY) { - json* child = new json(nullptr, val); + gb_json* child = new gb_json(nullptr, val); arr_val_.push_back(child); } return *this; } -json& json::operator+=(int val) +gb_json& gb_json::operator+=(int val) { if (type_ == VAL_TYPE_ARRAY) { - json* child = new json(nullptr, val); + gb_json* child = new gb_json(nullptr, val); arr_val_.push_back(child); } return *this; } -json& json::operator+=(double val) +gb_json& gb_json::operator+=(double val) { if (type_ == VAL_TYPE_ARRAY) { - json* child = new json(nullptr, val); + gb_json* child = new gb_json(nullptr, val); arr_val_.push_back(child); } return *this; } -json& json::operator+=(const char* val) +gb_json& gb_json::operator+=(const char* val) { if (type_ == VAL_TYPE_ARRAY) { - json* child = new json(nullptr, val); + gb_json* child = new gb_json(nullptr, val); arr_val_.push_back(child); } return *this; } -json& json::operator+=(json* val) +gb_json& gb_json::operator+=(gb_json* val) { if (type_ == VAL_TYPE_ARRAY) { @@ -611,15 +620,15 @@ json& json::operator+=(json* val) return *this; } -json& json::operator-=(int ind) +gb_json& gb_json::operator-=(int ind) { remove(ind); return *this; } -bool json::remove(const char* key) +bool gb_json::remove(const char* key) { - json* child = find_child(key, true); + gb_json* child = find_child(key, true); if (child) { @@ -631,7 +640,7 @@ bool json::remove(const char* key) return false; } } -bool json::remove(json* child) +bool gb_json::remove(gb_json* child) { if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) { @@ -649,7 +658,7 @@ bool json::remove(json* child) return false; } -bool json::remove(int ind) +bool gb_json::remove(int ind) { bool ret = false; @@ -666,7 +675,7 @@ bool json::remove(int ind) return ret; } -int json::index(json* child) +int gb_json::index(gb_json* child) { if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) { @@ -679,7 +688,7 @@ int json::index(json* child) return -1; } -int json::index_move_to(json* child, int ind) +int gb_json::index_move_to(gb_json* child, int ind) { int i = index(child); @@ -696,7 +705,7 @@ int json::index_move_to(json* child, int ind) return ind; } -bool json::value(bool& val) +bool gb_json::value(bool& val) { bool ret = false; @@ -708,7 +717,7 @@ bool json::value(bool& val) return ret; } -bool json::value(int& val) +bool gb_json::value(int& val) { bool ret = false; @@ -720,7 +729,7 @@ bool json::value(int& val) return ret; } -bool json::value(double& val) +bool gb_json::value(double& val) { bool ret = false; @@ -732,7 +741,7 @@ bool json::value(double& val) return ret; } -bool json::value(std::string& val) +bool gb_json::value(std::string& val) { bool ret = false; @@ -744,7 +753,7 @@ bool json::value(std::string& val) return ret; } -json& json::operator=(bool val) +gb_json& gb_json::operator=(bool val) { if (is_leaf_node()) { @@ -754,7 +763,7 @@ json& json::operator=(bool val) return *this; } -json& json::operator=(int val) +gb_json& gb_json::operator=(int val) { if (is_leaf_node()) { @@ -764,7 +773,7 @@ json& json::operator=(int val) return *this; } -json& json::operator=(double val) +gb_json& gb_json::operator=(double val) { if (is_leaf_node()) { @@ -774,7 +783,7 @@ json& json::operator=(double val) return *this; } -json& json::operator=(const char* val) +gb_json& gb_json::operator=(const char* val) { if (is_leaf_node()) { diff --git a/device/gxx-linux/usb/src/common/json/json.h b/device/gxx-linux/usb/src/async_model/common/json/gb_json.h similarity index 66% rename from device/gxx-linux/usb/src/common/json/json.h rename to device/gxx-linux/usb/src/async_model/common/json/gb_json.h index 3adff81..e22e74e 100644 --- a/device/gxx-linux/usb/src/common/json/json.h +++ b/device/gxx-linux/usb/src/async_model/common/json/gb_json.h @@ -48,7 +48,7 @@ public: struct cJSON; -class json : public refer +class gb_json : public refer { enum val_type { @@ -69,24 +69,24 @@ class json : public refer double dval; }simple_val_; std::string strval_; - std::vector arr_val_; + std::vector arr_val_; size_t cur_child_; - static std::string object_key(json* jsn); - static std::string array_key(json* jsn); + static std::string object_key(gb_json* jsn); + static std::string array_key(gb_json* jsn); void from_cjson(cJSON* cj); - json* find_child(const char* key, bool remove = false); + gb_json* find_child(const char* key, bool remove = false); public: - json(char* json_txt = 0); + gb_json(char* json_txt = 0); protected: - json(const char* key, bool val); - json(const char* key, int val); - json(const char* key, double val); - json(const char* key, const char* val); - ~json(); + gb_json(const char* key, bool val); + gb_json(const char* key, int val); + gb_json(const char* key, double val); + gb_json(const char* key, const char* val); + ~gb_json(); public: // parse/un-parse ... @@ -104,45 +104,45 @@ public: bool get_value(const char* key, int& val); bool get_value(const char* key, double& val); bool get_value(const char* key, std::string& val); - bool get_value(const char* key, json*& val); + bool get_value(const char* key, gb_json*& val); // enumeration ... size_t children(void); // return children count if was object or array, or else -1 returned - json* child(size_t ind); - json* first_child(void); - json* next_child(void); + gb_json* child(size_t ind); + gb_json* first_child(void); + gb_json* next_child(void); // change the item matching 'key', otherwise add a new item bool set_value(const char* key, bool val); bool set_value(const char* key, int val); bool set_value(const char* key, double val); bool set_value(const char* key, const char* val); - bool set_value(const char* key, json* val); + bool set_value(const char* key, gb_json* val); // operator+= only for array - json& operator+=(bool val); - json& operator+=(int val); - json& operator+=(double val); - json& operator+=(const char* val); - json& operator+=(json* val); + gb_json& operator+=(bool val); + gb_json& operator+=(int val); + gb_json& operator+=(double val); + gb_json& operator+=(const char* val); + gb_json& operator+=(gb_json* val); // remove item - json& operator-=(int ind); + gb_json& operator-=(int ind); bool remove(const char* key); - bool remove(json* child); + bool remove(gb_json* child); bool remove(int ind); // position management - int index(json* child); - int index_move_to(json* child, int ind); + int index(gb_json* child); + int index_move_to(gb_json* child, int ind); // leaf node value ... bool value(bool& val); bool value(int& val); bool value(double& val); bool value(std::string& val); - json& operator=(bool val); - json& operator=(int val); - json& operator=(double val); - json& operator=(const char* val); + gb_json& operator=(bool val); + gb_json& operator=(int val); + gb_json& operator=(double val); + gb_json& operator=(const char* val); }; diff --git a/device/gxx-linux/usb/src/common/log_util.cpp b/device/gxx-linux/usb/src/async_model/common/log_util.cpp similarity index 91% rename from device/gxx-linux/usb/src/common/log_util.cpp rename to device/gxx-linux/usb/src/async_model/common/log_util.cpp index 345df2f..e8036a5 100644 --- a/device/gxx-linux/usb/src/common/log_util.cpp +++ b/device/gxx-linux/usb/src/async_model/common/log_util.cpp @@ -160,6 +160,18 @@ int32_t log_cls::log_when_err(int32_t err, const char* oper_desc, log_level leve return err; } +void log_cls::log_memory_usage(const char* tag, bool print_screen, const char* prog_name) +{ + std::string memu("--Memory usage of "); + + memu += tag; + memu += ": " + sys_util::format_readable_bytes(sys_util::get_memory_usage(prog_name)) + "--"; + + if(print_screen) + printf("%s\n", memu.c_str()); + else if (log_cls::inst_) + log_cls::inst_->log(LOG_LEVEL_DEBUG, "%s\n", memu.c_str()); +} log_level log_cls::get_log_level(void) { if (log_cls::inst_) diff --git a/device/gxx-linux/usb/src/common/log_util.h b/device/gxx-linux/usb/src/async_model/common/log_util.h similarity index 90% rename from device/gxx-linux/usb/src/common/log_util.h rename to device/gxx-linux/usb/src/async_model/common/log_util.h index b298dc9..b8e5bd2 100644 --- a/device/gxx-linux/usb/src/common/log_util.h +++ b/device/gxx-linux/usb/src/async_model/common/log_util.h @@ -60,6 +60,7 @@ public: } } static int32_t log_when_err(int32_t err, const char* oper_desc, log_level level = LOG_LEVEL_WARNING); // log as: oper_desc = strerror(errno)\n. return real error number errno + static void log_memory_usage(const char* tag, bool print_screen = false/*call printf if this was true, or write down to file*/, const char* prog_name = "scan"); static log_level get_log_level(void); static std::string get_log_file(void); diff --git a/device/gxx-linux/usb/src/common/packet.h b/device/gxx-linux/usb/src/async_model/common/packet.h similarity index 93% rename from device/gxx-linux/usb/src/common/packet.h rename to device/gxx-linux/usb/src/async_model/common/packet.h index c30b7bd..00d1948 100644 --- a/device/gxx-linux/usb/src/common/packet.h +++ b/device/gxx-linux/usb/src/async_model/common/packet.h @@ -9,9 +9,13 @@ #endif #include +#define TEMPORARY_API + /////////////////////////////////////////////////////////////////////////////// // definitions ... #define CONFIG_NAME_MAX_LEN 32 // max bytes of configuration name +#define FLOAT_PRECISION .000001f +#define IS_FLOAT_EQUAL(x, y) (-FLOAT_PRECISION <= (x) - (y) && (x) - (y) <= FLOAT_PRECISION) #define MAKE_WORD(b0, b1) (((b0) & 0xff) | (((b1) << 8) & 0x0ff00)) #define ROGER(cmd) cmd##_ROGER #define PAIR_COMMAND(cmd) \ @@ -82,7 +86,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 + PAIR_COMMAND(PACK_CMD_SCAN_PAPER), // device -> host, ONE paper has passed through the CIS. PACK_BASE::data - index 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 @@ -107,6 +111,13 @@ enum packet_cmd PACK_CMD_TOKEN_GET = 900, // Obtain the token of the required command, [in] PACK_BASE, [out] - PACK_BASE::payload - LPOPERTOKEN }; +enum img_cb_type +{ + IMG_CB_IMAGE = 0, + IMG_CB_STATUS, + IMG_CB_STOPPED, +}; + enum scanner_status { SCANNER_STATUS_READY = 0x10000, // status beginning, avoiding conficts with standards/system error code @@ -134,6 +145,15 @@ enum scanner_status SCANNER_STATUS_CFG_CHANGED, // PACK_BASE::payload - LPCFGVAL }; +// option affection if value changed, see SANE_INFO_xxx +enum opt_affect +{ + OPT_AFFECT_NONE = 0, + OPT_AFFECT_INEXACT = 1, + OPT_AFFECT_OTHERS = 2, + OPT_AFFECT_IMG_PARAM = 4, +}; + enum img_format { IMG_FMT_UNKNOWN = 0, // unknown format @@ -156,23 +176,25 @@ enum img_compression }; enum img_status { - 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 + IMG_STATUS_OK = 0, // normal + IMG_STATUS_DOUBLE = 1 << 0, // double-feeded paper + IMG_STATUS_JAM = 1 << 1, // jammed paper + IMG_STATUS_STAPLE = 1 << 2, // staples on the paper + IMG_STATUS_SIZE_ERR = 1 << 3, // size check failed + IMG_STATUS_DOGEAR = 1 << 4, // paper has dogear - common + IMG_STATUS_DOGEAR_PARTIAL = 1 << 5, // dogear - scanned partial + IMG_STATUS_BLANK = 1 << 6, // blank image }; enum data_type { DATA_TYPE_BOOL = 0, // (bool*) + DATA_TYPE_INT4, // (uint32_t*) + DATA_TYPE_FLOAT, // (double*) + DATA_TYPE_STRING, // (char*) with max_len space. befor and include me, keep same with SANE_TYPE_BOOL, SANE_TYPE_xxx ... + DATA_TYPE_INT1, // (uint8_t*) DATA_TYPE_INT2, // (uint16_t*) - DATA_TYPE_INT4, // (uint32_t*) DATA_TYPE_INT8, // (uint64_t*) - DATA_TYPE_FLOAT, // (double*) - DATA_TYPE_STRING, // (char*) with max_len space DATA_TYPE_CUSTOM, }; @@ -252,7 +274,7 @@ typedef struct _config_val uint8_t val_off; // option value offset in data uint8_t after_do; // see SANE_INFO_xxx in sane.h uint16_t val_size; // real size of value - uint16_t max_size; // max size of this option, this value has given in json::size + uint16_t max_size; // max size of this option, this value has given in gb_json::size char data[0]; // contains value and name. fetch them according name_off and val_off members. }CFGVAL, *LPCFGVAL; @@ -264,10 +286,10 @@ typedef struct _img_pos 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, enum clr_channel. (image-collector set) - uint64_t status : 4; // img_status. (image-collector set) + uint64_t status : 7; // 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 - uint64_t reserved : 6; // reserved + uint64_t reserved : 3; // reserved STRUCT_CONSTRUCTOR(_img_pos) }IMGPOS, * LPIMGPOS; diff --git a/device/gxx-linux/testusb/usb-rk3399/src/common/referer.cpp b/device/gxx-linux/usb/src/async_model/common/referer.cpp similarity index 100% rename from device/gxx-linux/testusb/usb-rk3399/src/common/referer.cpp rename to device/gxx-linux/usb/src/async_model/common/referer.cpp diff --git a/device/gxx-linux/usb/src/common/referer.h b/device/gxx-linux/usb/src/async_model/common/referer.h similarity index 98% rename from device/gxx-linux/usb/src/common/referer.h rename to device/gxx-linux/usb/src/async_model/common/referer.h index 47cb161..20218b7 100644 --- a/device/gxx-linux/usb/src/common/referer.h +++ b/device/gxx-linux/usb/src/async_model/common/referer.h @@ -186,6 +186,10 @@ public: } } } + size_t count(void) + { + return threads_.size(); + } }; diff --git a/device/gxx-linux/usb/src/async_model/common/sane_cfg.cpp b/device/gxx-linux/usb/src/async_model/common/sane_cfg.cpp new file mode 100644 index 0000000..67e4fb2 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/common/sane_cfg.cpp @@ -0,0 +1,911 @@ +#include "sane_cfg.h" + +#include "json/gb_json.h" +#include "log_util.h" + + + + + + + + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// sane_cfg_provider: +sane_cfg_provider::sane_cfg_provider() +{} +sane_cfg_provider::~sane_cfg_provider() +{} + + std::string sane_cfg_provider::to_readable_string(void* data, data_type type) + { + if(type == DATA_TYPE_BOOL) + return *(bool*)data ? "true" : "false"; + else if(type == DATA_TYPE_INT4) + return std::to_string(*(int*)data); + else if(type == DATA_TYPE_FLOAT) + return std::to_string(*(double*)data); + else + return (char*)data; + } +std::string sane_cfg_provider::sane_option_value_get(gb_json* jsn, const char* key, std::string* strval) +{ + std::string type(""), ret(""); + bool got = false; + + if (jsn->get_value("type", type)) + { + if (type == "bool") + { + bool v = false; + if ((got = jsn->get_value(key, v))) + ret = std::string((char*)&v, sizeof(v)); + if(strval) + *strval = v ? "true" : "false"; + } + else if (type == "int") + { + int v = 0; + if ((got = jsn->get_value(key, v))) + ret = std::string((char*)&v, sizeof(v)); + if(strval) + *strval = std::to_string(v); + } + else if (type == "float") + { + double v = false; + if ((got = jsn->get_value(key, v))) + ret = std::string((char*)&v, sizeof(v)); + if(strval) + { + char buf[80] = {0}; + sprintf(buf, "%f", v); + *strval = buf; + } + } + else + { + got = jsn->get_value(key, ret); + if(strval) + *strval = ret; + } + if(!got) + { + printf("Failed to get '%s' value in JSON %s\n", key, jsn->to_string().c_str()); + } + } + else + { + printf("Lost 'type' field of json: %s\n", jsn->to_string().c_str()); + } + + return std::move(ret); +} +bool sane_cfg_provider::sane_option_value_set(gb_json* jsn, void* data, const char* key) +{ + std::string type(""); + bool ret = jsn->get_value("type", type); + + if (ret) + { + if (type == "bool") + { + ret = jsn->set_value(key, *(bool*)data); + } + else if (type == "int") + { + ret = jsn->set_value(key, *(int*)data); + } + else if (type == "float") + { + ret = jsn->set_value(key, *(double*)data); + } + else + { + ret = jsn->set_value(key, (char*)data); + } + } + + return ret; +} +bool sane_cfg_provider::sane_refine_range(gb_json* jsn, void* data, size_t* len) +{ + gb_json* range = nullptr; + bool ok = true; + + if(jsn->get_value("range", range) && range) + { + std::string type(""); + + jsn->get_value("type", type); + if(type == "int") + { + int val = 0, step = 1; + + range->get_value("step", step); + if(range->get_value("min", val)) + { + int upper = 0; + range->get_value("max", upper); + if(*(int*)data < val) + { + *(int*)data = val; + *len = sizeof(val); + ok = false; + } + else if(*(int*)data > upper) + { + *(int*)data = upper; + *len = sizeof(val); + ok = false; + } + else if((*(int*)data - val) % step) + { + int u = upper; + upper = *(int*)data - val; + upper += step / 2; + upper /= step; + upper *= step; + upper += val; + if(upper > u) + upper = u; + *(int*)data = upper; + *len = sizeof(val); + ok = false; + } + } + else + { + gb_json* en = range->first_child(); + + ok = false; + while(en) + { + if(en->value(val) && val == *(int*)data) + { + ok = true; + en->release(); + break; + } + en->release(); + en = range->next_child(); + } + if(!ok) + { + jsn->get_value("cur", val); + *(int*)data = val; + *len = sizeof(val); + } + } + } + else if(type == "float") + { + double val = .0f, step = 1.0f; + range->get_value("step", step); + if(range->get_value("min", val)) + { + double upper = 0; + range->get_value("max", upper); + if(*(double*)data < val) + { + *(double*)data = val; + *len = sizeof(val); + ok = false; + } + else if(*(double*)data > upper) + { + *(double*)data = upper; + *len = sizeof(val); + ok = false; + } + else + { + double u = upper; + upper = *(double*)data - val; + upper /= step; + upper -= (int)upper; + if(upper > .05f) + { + upper = *(double*)data - val; + upper /= step; + upper += .5f; + upper = (int)upper; + upper *= step; + upper += val; + if(upper > u) + upper = u; + + *(double*)data = upper; + *len = sizeof(val); + ok = false; + } + } + } + else + { + gb_json* en = range->first_child(); + + ok = false; + while(en) + { + if(en->value(val) && IS_FLOAT_EQUAL(val, *(double*)data)) + { + ok = true; + en->release(); + break; + } + en->release(); + en = range->next_child(); + } + if(!ok) + { + jsn->get_value("cur", val); + *(double*)data = val; + *len = sizeof(val); + } + } + } + else if(type == "string") + { + gb_json* en = range->first_child(); + + ok = false; + while(en) + { + if(en->value(type) && type == (char*)data) + { + ok = true; + en->release(); + break; + } + + en->release(); + en = range->next_child(); + } + if(!ok) + { + jsn->get_value("cur", type); + memcpy(data, type.c_str(), type.length()); + *len = type.length(); + } + } + + range->release(); + } + + return ok; +} +void sane_cfg_provider::update_option_enable_status(gb_json* opt, std::function get_opt) +{ + gb_json* depends = nullptr, *item = nullptr; + bool able = true, oper_and = false; + int type = 0; + std::string name(""), val(""); + + if(opt->get_value("depend_and", depends) && depends) + { + oper_and = true; + } + else if(opt->get_value("depend_or", depends) && depends) + { + oper_and = false; + } + + if(depends) + { + item = depends->first_child(); + while(item) + { + std::string exp(""); + if(item->value(exp)) + { + able = sane_cfg_provider::is_depends_item_ok(exp, &name, &type, &val, get_opt); + } + item->release(); + // if((!able && oper_and) || (able && !oper_and)) + if(able ^ oper_and) + break; + item = depends->next_child(); + } + depends->release(); + opt->set_value("enabled", able); + } +} +data_type sane_cfg_provider::type_from_string(const char* type_desc) +{ + if(strcmp(type_desc, "bool") == 0) + return DATA_TYPE_BOOL; + if(strcmp(type_desc, "int") == 0) + return DATA_TYPE_INT4; + if(strcmp(type_desc, "float") == 0) + return DATA_TYPE_FLOAT; + if(strcmp(type_desc, "string") == 0) + return DATA_TYPE_STRING; + + return DATA_TYPE_CUSTOM; +} + bool sane_cfg_provider::raw_value_in_json(gb_json* root, const char* key, std::string& val) + { + bool ret = true, bv = false; + int nv = 0; + double fv = .0f; + + if(root->get_value(key, bv)) + { + val = std::string((char*)&bv, sizeof(bv)); + } + else if(root->get_value(key, nv)) + { + val = std::string((char*)&nv, sizeof(nv)); + } + else if(root->get_value(key, fv)) + { + val = std::string((char*)&fv, sizeof(fv)); + } + else + { + ret = root->get_value(key, val); + } + + return ret; + } + +bool sane_cfg_provider::try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) +{ + bool oper_not = false, calc = true, handled = false; + size_t pos = exp.find("=="); + + if(pos == std::string::npos) + { + pos = exp.find("!="); + if(pos != std::string::npos) + { + oper_not = true; + } + } + if(pos != std::string::npos) + { + handled = true; + if(pos) + { + std::string types(""); + char buf[40] = {0}, *mem = nullptr; + size_t l = sizeof(buf) - 1; + + *name = exp.substr(0, pos); + get_opt(name->c_str(), buf, &l, "type"); + *type = sane_cfg_provider::type_from_string(buf); + l = 0; + get_opt(name->c_str(), mem, &l, "cur"); + mem = new char[l + 4]; + l += 4; + get_opt(name->c_str(), mem, &l, "cur"); + *val = std::string(mem, l); + delete[] mem; + } + exp.erase(0, pos + 2); + + if(*type == DATA_TYPE_BOOL) + { + calc = (*(bool*)val->c_str()) == (exp == "true"); + } + else if(*type == DATA_TYPE_INT4) + { + // in range ? + if(exp[0] == '[') + { + int lower = atoi(exp.c_str() + 1), + upper = 0; + pos = exp.find(","); + if(pos++ != std::string::npos) + upper = atoi(exp.c_str() + pos); + calc = lower <= *(int*)val->c_str() && *(int*)val->c_str() <= upper; + } + else + { + calc == *(int*)val->c_str() == atoi(exp.c_str()); + } + } + else if(*type == DATA_TYPE_FLOAT) + { + // in range ? + if(exp[0] == '[') + { + double lower = atof(exp.c_str() + 1), + upper = 0; + pos = exp.find(","); + if(pos++ != std::string::npos) + upper = atof(exp.c_str() + pos); + calc = lower <= *(double*)val->c_str() && *(double*)val->c_str() <= upper; + } + else + { + calc = IS_FLOAT_EQUAL(*(double*)val->c_str(), atof(exp.c_str())); + } + } + else if(*type == DATA_TYPE_STRING) + { + calc = *val == exp; + } + else + { + log_cls::log(LOG_LEVEL_FATAL, "Logic-operation error: un-supported type(%d) in '%s%s'\n", *type, oper_not ? "!=" : "==", exp.c_str()); + } + + *result = oper_not ^ calc; + } + + return handled; +} +bool sane_cfg_provider::try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) +{ + bool oper_not = false, calc = true, handled = false; + size_t pos = exp.find(">"); + + if(pos == std::string::npos) + { + pos = exp.find("<="); + if(pos != std::string::npos) + { + oper_not = true; + } + } + if(pos != std::string::npos) + { + handled = true; + if(pos) + { + std::string types(""); + char buf[40] = {0}, *mem = nullptr; + size_t l = sizeof(buf) - 1; + + *name = exp.substr(0, pos); + get_opt(name->c_str(), buf, &l, "type"); + *type = sane_cfg_provider::type_from_string(buf); + l = 0; + get_opt(name->c_str(), mem, &l, "cur"); + mem = new char[l + 4]; + l += 4; + get_opt(name->c_str(), mem, &l, "cur"); + *val = std::string(mem, l); + delete[] mem; + } + exp.erase(0, pos + 1 + oper_not); + + if(*type == DATA_TYPE_INT4) + { + calc == *(int*)val->c_str() > atoi(exp.c_str()); + } + else if(*type == DATA_TYPE_FLOAT) + { + calc = *(double*)val->c_str() > atof(exp.c_str()); + } + else + { + log_cls::log(LOG_LEVEL_FATAL, "Logic-operation error: un-supported type(%d) in '%s%s'\n", *type, oper_not ? "<=" : ">", exp.c_str()); + } + + *result = oper_not ^ calc; + } + + return handled; +} +bool sane_cfg_provider::try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) +{ + bool oper_not = false, calc = true, handled = false; + size_t pos = exp.find("<"); + + if(pos == std::string::npos) + { + pos = exp.find(">="); + if(pos != std::string::npos) + { + oper_not = true; + } + } + if(pos != std::string::npos) + { + handled = true; + if(pos) + { + std::string types(""); + char buf[40] = {0}, *mem = nullptr; + size_t l = sizeof(buf) - 1; + + *name = exp.substr(0, pos); + get_opt(name->c_str(), buf, &l, "type"); + *type = sane_cfg_provider::type_from_string(buf); + l = 0; + get_opt(name->c_str(), mem, &l, "cur"); + mem = new char[l + 4]; + l += 4; + get_opt(name->c_str(), mem, &l, "cur"); + *val = std::string(mem, l); + delete[] mem; + } + exp.erase(0, pos + 1 + oper_not); + + if(*type == DATA_TYPE_INT4) + { + calc == *(int*)val->c_str() < atoi(exp.c_str()); + } + else if(*type == DATA_TYPE_FLOAT) + { + calc = *(double*)val->c_str() < atof(exp.c_str()); + } + else + { + log_cls::log(LOG_LEVEL_FATAL, "Logic-operation error: un-supported type(%d) in '%s%s'\n", *type, oper_not ? ">=" : "<", exp.c_str()); + } + + *result = oper_not ^ calc; + } + + return handled; +} +bool sane_cfg_provider::is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt) +{ + // ==, >, < + // !=, <=, >= + bool ok = true; + + if(!sane_cfg_provider::try_equal(exp, name, type, val, get_opt, &ok)) + { + if(!sane_cfg_provider::try_great(exp, name, type, val, get_opt, &ok)) + { + sane_cfg_provider::try_less(exp, name, type, val, get_opt, &ok); + } + } + + + return ok; +} + +int32_t sane_cfg_provider::inner_get_config(gb_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) + { + gb_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 + { + ret = ENOENT; + } + } + 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; +} + + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// : + +sane_cfg_mgr::sane_cfg_mgr() +{} +sane_cfg_mgr::~sane_cfg_mgr() +{ + cfg_api_.clear(); + for (auto& v : sane_waiters_) + v->release(); + sane_waiters_.clear(); +} + +gb_json* sane_cfg_mgr::load_all_configs(sane_cfg_provider* prvd) +{ + char * buf = nullptr; + size_t len = 0; + int32_t err = prvd->get_config(buf, &len); + gb_json * jsn = nullptr; + + if (err == ENOMEM) + { + len = ALIGN_INT(len, 8); + buf = (char*)malloc(len); + if (buf) + { + err = prvd->get_config(buf, &len); + if (err == 0) + { + jsn = new gb_json(); + if(!jsn->attach_text(buf)) + { + jsn->release(); + jsn = nullptr; + } + } + free(buf); + } + } + + return jsn; +} + +void sane_cfg_mgr::add_sane_api(const char* name, int ver, sane_cfg_provider* prvd) +{ + if (cfg_api_.count(name) && cfg_api_[name].ver >= ver) + return; + + cfg_api_[name].prvd = prvd; + if(std::find(cfg_sn_.begin(), cfg_sn_.end(), name) == cfg_sn_.end()) + cfg_sn_.push_back(name); +} +void sane_cfg_mgr::refresh_api(sane_cfg_provider* prvd, std::vector* given) +{ + char * buf = nullptr; + size_t len = 0; + gb_json *jsn = sane_cfg_mgr::load_all_configs(prvd), *child = nullptr; + + if (!jsn) + return; + + if (given) + { + for (auto& v : *given) + { + if (jsn->get_value(v.c_str(), child) && child) + { + int ver = 0; + if (child->get_value("ver", ver)) + add_sane_api(v.c_str(), ver, prvd); + child->release(); + } + } + } + else + { + child = jsn->first_child(); + while (child) + { + int ver = 0; + if (child->get_value("ver", ver)) + add_sane_api(child->key().c_str(), ver, prvd); + child->release(); + child = jsn->next_child(); + } + } + jsn->release(); +} +void sane_cfg_mgr::on_sane_provider_changed(sane_cfg_provider* prvd, bool add) +{ + if (add) + { + refresh_api(prvd); + } + else + { + std::vector lost; + for (auto& v : cfg_api_) + { + if (v.second.prvd == prvd) + lost.push_back(v.first); + } + for (auto& v : lost) + { + cfg_api_.erase(v); + + std::vector::iterator it = std::find(cfg_sn_.begin(), cfg_sn_.end(), v); + if(it != cfg_sn_.end()) + cfg_sn_.erase(it); + } + + char *buf = nullptr; + size_t size = 0, len = 0; + int32_t err = 0; + + for (auto& v : sane_waiters_) + { + refresh_api(v, &lost); + } + } + update_enable_status(); +} +std::string sane_cfg_mgr::get_all_configurations(void) +{ + std::map jsns; + gb_json* all = new gb_json(), * child = nullptr; + std::string text(""); + + for (auto& v : sane_waiters_) + { + gb_json* jsn = sane_cfg_mgr::load_all_configs(v); + if (jsn) + { + jsns[v] = jsn; + } + } + + for (auto& v : cfg_sn_) + { + if (cfg_api_.count(v) && jsns.count(cfg_api_[v].prvd)) + { + if (jsns[cfg_api_[v].prvd]->get_value(v.c_str(), child) && child) + { + all->set_value(v.c_str(), child); + child->release(); + } + } + } + text = all->to_string(); + all->release(); + + for (auto& v : jsns) + v.second->release(); + jsns.clear(); + + return std::move(text); +} +void sane_cfg_mgr::update_enable_status(void) +{ + auto get_opt = [&](const char* cfg_name, void* buf, size_t* len, const char* key) -> int32_t + { + std::string val(""); + int32_t ret = 0; + + for(auto& v: sane_waiters_) + { + ret = v->get_value(cfg_name, key, val); + if(ret != ENOENT) + break; + } + + if(ret == 0) + { + if(*len < val.length()) + { + *len = val.length(); + ret = ENOMEM; + } + else + { + memcpy(buf, val.c_str(), val.length()); + *len = val.length(); + } + } + + return ret; + }; + + for(auto& v: sane_waiters_) + { + v->update_enabled(get_opt); + } +} + +int sane_cfg_mgr::reg_sane_provider(sane_cfg_provider* prvd) +{ + LOCKER lock(locker_); + if (std::find(sane_waiters_.begin(), sane_waiters_.end(), prvd) == sane_waiters_.end()) + { + sane_waiters_.push_back(prvd); + prvd->add_ref(); + on_sane_provider_changed(prvd, true); + + return 0; + } + + return EEXIST; +} +int sane_cfg_mgr::unreg_sane_provider(sane_cfg_provider* prvd) +{ + LOCKER lock(locker_); + std::vector::iterator it = std::find(sane_waiters_.begin(), sane_waiters_.end(), prvd); + + if (it == sane_waiters_.end()) + return ENOENT; + + sane_waiters_.erase(it); + on_sane_provider_changed(prvd, false); + prvd->release(); + + return 0; +} + +// following APIs' parameters are same as sane_cfg_provider ... +int32_t sane_cfg_mgr::get_config(std::string& text, const char* cfg_name, std::string* str) +{ + if (cfg_name) + { + if (*cfg_name && cfg_api_.count(cfg_name)) + { + size_t len = 0; + int32_t err = cfg_api_[cfg_name].prvd->get_config(nullptr, &len, cfg_name, str); + + if (err == ENOMEM) + { + text.resize(len + 1); + err = cfg_api_[cfg_name].prvd->get_config(&text[0], &len, cfg_name, str); + text.resize(len); + } + + return err; + } + else + return ENOENT; + } + else + { + // get all ... + text = std::move(get_all_configurations()); + + return 0; + } +} +int32_t sane_cfg_mgr::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + if (cfg_name) + { + if (cfg_api_.count(cfg_name)) + { + uint32_t affect = 0; + int32_t ret = cfg_api_[cfg_name].prvd->set_config(cfg_name, data, len, &affect); + + if(affect & OPT_AFFECT_OTHERS) + { + update_enable_status(); + } + + if(afterdo) + *afterdo = affect; + return ret; + } + else + return ENOENT; + } + else + return EINVAL; +} + diff --git a/device/gxx-linux/usb/src/common/sane_cfg.h b/device/gxx-linux/usb/src/async_model/common/sane_cfg.h similarity index 52% rename from device/gxx-linux/usb/src/common/sane_cfg.h rename to device/gxx-linux/usb/src/async_model/common/sane_cfg.h index 5ba98fc..25d571e 100644 --- a/device/gxx-linux/usb/src/common/sane_cfg.h +++ b/device/gxx-linux/usb/src/async_model/common/sane_cfg.h @@ -5,11 +5,13 @@ // created on 2023-04-04 -#include "referer.h" -#include "data.h" +#include "common/referer.h" +#include "common/packet.h" + #include #include #include +#include //{ @@ -32,10 +34,21 @@ // "range": ["A3", "8开", "A4", "A4横向", "16开", "16开横向", "A5", "A5横向", "A6", "A6横向", "B4", "B5", "B5横向", "B6", "B6横向", "Letter", "Letter横向", "Double Letter", "LEGAL", "匹配原始尺寸", "最大扫描尺寸自动裁切", "最大扫描尺寸", "三联试卷"] // }, //} +enum sane_after_do +{ + SANE_AFTER_DO_NOTHING = 0, + SANE_AFTER_DO_RELOAD_PARAM, + SANE_AFTER_DO_RELOAD_OPTION, +}; -class json; +class gb_json; class sane_cfg_provider : public refer { + static bool try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result); + static bool try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result); + static bool try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result); + static bool is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt); + public: sane_cfg_provider(); @@ -43,11 +56,16 @@ protected: virtual ~sane_cfg_provider(); 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*/); + static std::string to_readable_string(void* data, data_type type); + static std::string sane_option_value_get(gb_json* jsn, const char* key = "cur"/*cur, default*/, std::string* strval = nullptr/*convert value into string*/); + static bool sane_option_value_set(gb_json* jsn, void* data, const char* key = "cur"/*cur, default*/); + static bool sane_refine_range(gb_json* jsn, void* data, size_t* len); // if 'data' is accept then return true, or else return false and new data set in 'data' and 'len' + static void update_option_enable_status(gb_json* opt, std::function get_opt); + static data_type type_from_string(const char* type_desc); + static bool raw_value_in_json(gb_json* root, const char* key, std::string& val); protected: - int32_t inner_get_config(json* root, void* buf, size_t* len, const char* cfg_name, std::string* strval); + int32_t inner_get_config(gb_json* root, void* buf, size_t* len, const char* cfg_name, std::string* strval); public: // Function: get all or given name configuration value @@ -83,9 +101,35 @@ public: // ENOENT - configuration 'cfg_name' was not found // EUCLEAN - content in 'data' was not exact, the exact value is stored in 'data', and bytes in 'len' virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) = 0; + + // Function: update field 'enabled' if a option changed and affect other options ... + // + // Parameters: get_opt - function to get option value, return value is the same as get_config + // + // cfg_name - option name + // + // buf - buffer to receive the option value + // + // len - [in]: length of 'buf'; [out]: real size of value + // + // key - the value key in JSON, e.g.: current value key is "cur" + // + // Return: none + virtual void update_enabled(std::function get_opt) = 0; + + // Function: get value of given key + // + // Parameters: name - option name + // + // key - key of the value in gb_json + // + // val = to receive the raw value. e.g. std::string(&bool, sizeof(bool)) + // + // Return: 0 - success, + // ENOENT - not found + virtual int32_t get_value(const char* name, const char* key, std::string& val) = 0; }; -class json; class sane_cfg_mgr : public refer { MUTEX locker_; @@ -96,16 +140,18 @@ class sane_cfg_mgr : public refer }SANEPROVIDER; std::vector sane_waiters_; std::map cfg_api_; + std::vector cfg_sn_; // record the origin sequence of configuration for cfg_api_ will sort void add_sane_api(const char* name, int ver, sane_cfg_provider* prvd); void refresh_api(sane_cfg_provider* prvd, std::vector* given = nullptr); void on_sane_provider_changed(sane_cfg_provider* prvd, bool add); std::string get_all_configurations(void); + void update_enable_status(void); public: sane_cfg_mgr(); - static json* load_all_configs(sane_cfg_provider* prvd); + static gb_json* load_all_configs(sane_cfg_provider* prvd); protected: ~sane_cfg_mgr(); @@ -115,22 +161,8 @@ public: int unreg_sane_provider(sane_cfg_provider* prvd); // return 0, ENOENT // following APIs' parameters are same as sane_cfg_provider ... - int32_t get_config(std::string& text, const char* cfg_name = nullptr, std::string* str = nullptr); + int32_t get_config(std::string& text, const char* cfg_name = nullptr, std::string* strval = nullptr); int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo); }; - -class img_processor : public sane_cfg_provider -{ -public: - img_processor(); - -protected: - ~img_processor(); - -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; -}; - diff --git a/device/gxx-linux/usb/src/common/sys_util.cpp b/device/gxx-linux/usb/src/async_model/common/sys_util.cpp similarity index 96% rename from device/gxx-linux/usb/src/common/sys_util.cpp rename to device/gxx-linux/usb/src/async_model/common/sys_util.cpp index d322ea4..94afd43 100644 --- a/device/gxx-linux/usb/src/common/sys_util.cpp +++ b/device/gxx-linux/usb/src/async_model/common/sys_util.cpp @@ -547,6 +547,46 @@ namespace sys_util return val; } + std::string get_ip(void) + { + std::string val(sys_util::get_command_output("ifconfig | grep broadcast")); + char buf[40] = { 0 }; + + if (sscanf(val.c_str(), " inet %s", buf)) + val = buf; + + return std::move(val); + } + std::string get_mac(void) + { + std::string val(sys_util::get_command_output("ifconfig | grep ether")); + char buf[40] = { 0 }; + + if (sscanf(val.c_str(), " ether %s", buf)) + val = buf; + + return std::move(val); + } + std::string load_mini_file(const char* path) + { + FILE* src = fopen(path, "rb"); + std::string cont(""); + + if(src) + { + int len = 0; + + fseek(src, 0, SEEK_END); + len = ftell(src); + cont.resize(len); + fseek(src, 0, SEEK_SET); + fread(&cont[0], 1, len, src); + fclose(src); + } + + return cont; + } + static uint64_t from_dec_str(const char* str, const char** end) { uint64_t val = 0; diff --git a/device/gxx-linux/usb/src/common/sys_util.h b/device/gxx-linux/usb/src/async_model/common/sys_util.h similarity index 97% rename from device/gxx-linux/usb/src/common/sys_util.h rename to device/gxx-linux/usb/src/async_model/common/sys_util.h index 34fe405..ab78c50 100644 --- a/device/gxx-linux/usb/src/common/sys_util.h +++ b/device/gxx-linux/usb/src/async_model/common/sys_util.h @@ -75,6 +75,10 @@ namespace sys_util bool trim_right(std::string& str, const char* space = " \t"); uint64_t from_hex_str(const char* hex, const char** end = nullptr); // convert 0x100 to 256. parameter 'end' to receive the stopped position + std::string get_ip(void); + std::string get_mac(void); + std::string load_mini_file(const char* path); + // Function: convert number string to integer, support hex, dec, oct and bin // // Parameter: str - number string. diff --git a/device/gxx-linux/usb/src/async_model/hardware/hardware.cpp b/device/gxx-linux/usb/src/async_model/hardware/hardware.cpp new file mode 100644 index 0000000..8df685f --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/hardware/hardware.cpp @@ -0,0 +1,485 @@ +#include "hardware.h" + +#include "common/json/gb_json.h" +//{ +// "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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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\":\"CIS\",\"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}},\"scan-count\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":true,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u7684\\u7eb8\\u5f20\\u6570\\u91cf\uFF0C\\u201C-1\\u201D\\u4e3a\\u8fde\\u7eed\\u626b\\u63cf\",\"type\":\"int\",\"cur\":-1,\"default\":-1,\"size\":4,\"range\":[-1,1,2,3,4,5,6,7,8,9,10]}}"; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class image_capture +#ifdef TEMPORARY_API +extern int32_t (*scan_start)(void); +extern int32_t (*scan_stop)(void); +extern int32_t (*set_dpi)(int*, int*); +extern int32_t (*set_scan_num)(int); +#endif + +image_capture::image_capture(std::function receiver) + : img_keeper_(receiver), cfg_(new gb_json()) +{ + cfg_->attach_text(&json_text[0]); + memset(&api_, 0, sizeof(api_)); +} +image_capture::~image_capture() +{ + cfg_->release(); +} + +int32_t image_capture::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(); + gb_json *child = nullptr; + + if(cfg_->get_value(name, child) && child) + { + sane_cfg_provider::sane_refine_range(child, data, len); + + 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; + } + else if(n == "scan-count") + { + set_scan_num(*(int*)data); + child->set_value("cur", *(int*)data); + } + child->release(); + } + + if (api) + { + ret = 0; + api(&val); + if (val != *(int*)data) + { + *(int*)data = val; + ret = EUCLEAN; + } + } + + return ret; +} + +int32_t image_capture::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 image_capture::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + int ret = ENOENT; + gb_json* child = nullptr; + + if (cfg_->get_value(cfg_name, child) && child) + { + bool exact = sane_cfg_provider::sane_refine_range(child, data, len); + 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; + } + if(!exact) + ret = EUCLEAN; + } + child->release(); + } + + return ret; +} +void image_capture::update_enabled(std::function get_opt) +{ + sane_cfg_provider::update_option_enable_status(cfg_, get_opt); +} +int32_t image_capture::get_value(const char* name, const char* key, std::string& val) +{ + gb_json* child = nullptr; + int32_t ret = ENOENT; + + if(cfg_->get_value(name, child) && child) + { + if(sane_cfg_provider::raw_value_in_json(child, key, val)) + ret = 0; + } + + return ret; +} + +int32_t image_capture::start(void) +{ +#ifdef TEMPORARY_API + return scan_start(); +#else + return EINVAL; +#endif +} +int32_t image_capture::stop(void) +{ +#ifdef TEMPORARY_API + return scan_stop(); +#else + return EINVAL; +#endif +} +int image_capture::set_dpi(int* dpi_x, int* dpi_y) +{ + return ::set_dpi(dpi_x, dpi_y); +} \ No newline at end of file diff --git a/device/gxx-linux/usb/src/async_model/hardware/hardware.h b/device/gxx-linux/usb/src/async_model/hardware/hardware.h new file mode 100644 index 0000000..4ee6361 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/hardware/hardware.h @@ -0,0 +1,73 @@ +#pragma once + +// image process interface classes +// +// created on 2023-04-19 +// + +#include "common/referer.h" +#include "common/packet.h" +#include "common/sane_cfg.h" +#include + +class gb_json; + +#define CIS_API std::function // return error code, set real value to parameter if in-value was not exact +#define CAPTURED_IMG_RECEIVER_PROTO void(int data_type/*img_cb_type*/, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status, bool img_new, bool img_over) + +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 image_capture : public sane_cfg_provider +{ + gb_json* cfg_; + CISAPI api_; + std::function img_keeper_; + + int32_t set(const char* name, void* data, size_t* len); + +public: + image_capture(std::function receiver); + +protected: + ~image_capture(); + + // 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; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + +public: + void set_api(LPCISAPI api); + +public: + int32_t start(void); + int32_t stop(void); + + // Function: set resolution of hardware/CIS + // + // Parameters: dpi_x - [in]resolution of x axis to be set; [out]applied value, not set if it was nullptr + // + // dpi_y - [in]resolution of y axis to be set; [out]applied value, not set if it was nullptr + // + // Return: always 0. if input value is not accessible, the exact value is stored into the var + int set_dpi(int* dpi_x, int* dpi_y); +}; + diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.cpp b/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.cpp new file mode 100644 index 0000000..3ce2341 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.cpp @@ -0,0 +1,193 @@ +#include "dogear.h" + + +#include "common/json/gb_json.h" +#include "imageprocess/ImageApplyDogEarDetection.h" + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// + + + +static std::string dogear_jsn("{\"is-check-dog-ear\":{\"category\":\"base\",\"readonly\":false,\"affect\":2,\"group\":\"feeder\",\"visible\":true,\"field\":\"imgproc\",\"pos\":10,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6298\\u89d2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u6587\\u7a3f\\u662f\\u5426\\u5b58\\u5728\\u6298\\u89d2\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"dog-ear-size\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"imgproc\",\"pos\":11,\"ver\":1,\"unit\":\"None\",\"title\":\" \\u6298\\u89d2\\u5927\\u5c0f\",\"desc\":\"\\u503c\\u8d8a\\u5c0f\\u80fd\\u68c0\\u6d4b\\u5230\\u7684\\u6298\\u89d2\\u8d8a\\u5c0f\",\"type\":\"int\",\"cur\":70,\"default\":70,\"size\":4,\"range\":{\"min\":0,\"max\":100,\"step\":1},\"depend_or\":[\"is-check-dog-ear==true\"]},\"dog-ear-size-outer\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":false,\"field\":\"imgproc\",\"pos\":12,\"ver\":1,\"unit\":\"None\",\"title\":\" \\u6298\\u89d2\\u5927\\u5c0f(\\u5728\\u56fe\\u7247\\u5916)\",\"desc\":\"\\u503c\\u8d8a\\u5c0f\\u80fd\\u68c0\\u6d4b\\u5230\\u7684\\u6298\\u89d2\\u8d8a\\u5c0f\",\"type\":\"int\",\"cur\":70,\"default\":70,\"size\":4,\"range\":{\"min\":0,\"max\":100,\"step\":1},\"depend_or\":[\"is-check-dog-ear==true\"]},\"dog-ear-zoom-x\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":false,\"field\":\"imgproc\",\"pos\":13,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u539f\\u56feX\\u8f74\\u7f29\\u653e\\u6bd4\\u4f8b\",\"desc\":\"\\u5BF9\\u4E8E\\u5927\\u5C3A\\u5BF8\\u56FE\\u50CF\\u800C\\u8A00\\u901A\\u8FC7zoom\\u7F29\\u5C0F\\u56FE\\u50CF\\u53EF\\u51CF\\u5C11\\u8BA1\\u7B97\\u91CF\\u3002\\u9ED8\\u8BA4\\u503C1.0\",\"type\":\"float\",\"cur\":1.0,\"default\":1.0,\"size\":8,\"range\":{\"min\":0.1,\"max\":4.0,\"step\":0.5},\"depend_or\":[\"is-check-dog-ear==true\"]},\"dog-ear-zoom-y\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":false,\"field\":\"imgproc\",\"pos\":14,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u539f\\u56fey\\u8f74\\u7f29\\u653e\\u6bd4\\u4f8b\",\"desc\":\"\\u5BF9\\u4E8E\\u5927\\u5C3A\\u5BF8\\u56FE\\u50CF\\u800C\\u8A00\\u901A\\u8FC7zoom\\u7F29\\u5C0F\\u56FE\\u50CF\\u53EF\\u51CF\\u5C11\\u8BA1\\u7B97\\u91CF\\u3002\\u9ED8\\u8BA4\\u503C1.0\",\"type\":\"float\",\"cur\":1.0,\"default\":1.0,\"size\":8,\"range\":{\"min\":0.1,\"max\":4.0,\"step\":0.5},\"depend_or\":[\"is-check-dog-ear==true\"]},\"dog-ear-threashold\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":false,\"field\":\"imgproc\",\"pos\":15,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u4e8c\\u503c\\u5316\\u9608\\u503c\",\"desc\":\"\\u6298\\u89d2\\u68c0\\u6d4b\\u4e8c\\u503c\\u5316\\u53c2\\u6570\",\"type\":\"int\",\"cur\":40,\"default\":40,\"size\":4,\"range\":{\"min\":10,\"max\":100,\"step\":5},\"depend_or\":[\"is-check-dog-ear==true\"]}}"); + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_algs +dogear::dogear() : dog_(new CImageApplyDogEarDetection()), root_(new gb_json()) + , name_("is-check-dog-ear"), pos_(0), ver_(0), enable_(true) + , threshold_(40), zoom_x_(1.0f), zoom_y_(1.0f), size_inner_(50), size_outer_(50) +{ + root_->attach_text(&dogear_jsn[0]); + + gb_json* child = nullptr; + + root_->get_value(name_.c_str(), child); + if(child) + { + int n = 0; + child->get_value("cur", enable_); + child->get_value("pos", n); pos_ = n; + child->get_value("ver", n); ver_ = n; + child->release(); + } + + // int threshold_; // dog-ear-threashold + // double zoom_x_; // dog-ear-zoom-x + // double zoom_y_; // dog-ear-zoom-y + // int size_inner_; // dog-ear-size + // int size_outer_; // dog-ear-size-outer + size_t len = 0; + +#define GET_INNER_VAR(v, n) \ + len = sizeof(v); \ + get_config(&v, &len, #n); + + GET_INNER_VAR(threshold_, dog-ear-threashold); + GET_INNER_VAR(zoom_x_, dog-ear-zoom-x); + GET_INNER_VAR(zoom_y_, dog-ear-zoom-y); + GET_INNER_VAR(size_inner_, dog-ear-size); + GET_INNER_VAR(size_outer_, dog-ear-size-outer); +} +dogear::~dogear() +{ + root_->release(); + delete dog_; +} + + +int32_t dogear::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + if(cfg_name) + { + return inner_get_config(root_, buf, len, cfg_name, strval); + } + else + { + if(!len) + return EINVAL; + + std::string val(root_->to_string()); + + if(*len < val.length()) + { + *len = val.length() + 4; + + return ENOMEM; + } + + strcpy((char*)buf, val.c_str()); + *len = val.length(); + } + + return 0; +} +int32_t dogear::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + gb_json* child = nullptr; + int32_t ret = ENOENT; + + if(root_->get_value(cfg_name, child) && child) + { + int val = 0; + + ret = 0; + if(strcmp(cfg_name, name_.c_str()) == 0) + { + enable_ = *(bool*)data; + child->set_value("cur", enable_); + } + else if(strcmp(cfg_name, "dog-ear-size") == 0) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + size_inner_ = *(int*)data; + } + else if(strcmp(cfg_name, "dog-ear-size-outer") == 0) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + size_outer_ = *(int*)data; + } + else if(strcmp(cfg_name, "dog-ear-threashold") == 0) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + threshold_ = *(int*)data; + } + else if(strcmp(cfg_name, "dog-ear-zoom-x") == 0) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + zoom_x_ = *(double*)data; + } + else if(strcmp(cfg_name, "dog-ear-zoom-y") == 0) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + zoom_y_ = *(double*)data; + } + dog_->setDistance(size_inner_, size_outer_, threshold_, zoom_x_, zoom_y_); + + if(afterdo) + { + child->get_value("affect", val); + *afterdo = val; + } + + child->release(); + } + + return ret; +} +void dogear::update_enabled(std::function get_opt) +{ + gb_json* child = root_->first_child(); + while(child) + { + sane_cfg_provider::update_option_enable_status(child, get_opt); + child->release(); + child = root_->next_child(); + } +} +int32_t dogear::get_value(const char* name, const char* key, std::string& val) +{ + int32_t ret = ENOENT; + gb_json* child = nullptr; + + if(root_->get_value(name, child) && child) + { + ret = sane_cfg_provider::raw_value_in_json(child, key, val) ? 0 : ENOENT; + child->release(); + } + + return ret; +} + +img_one_paper* dogear::execute(img_one_paper* img) +{ + for(auto& v : img->images_queue()) + dog_->apply(v, 0); + img->add_ref(); + + return img; +} +bool dogear::is_enabled(std::function get_opt_value) +{ + return enable_; +} + +uint32_t dogear::position(void) +{ + return pos_; +} +uint32_t dogear::version(void) +{ + return ver_; +} +const char* dogear::option_name(void) +{ + return name_.c_str(); +} + + diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.h b/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.h new file mode 100644 index 0000000..0d5692e --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.h @@ -0,0 +1,189 @@ +#pragma once + +// dogear algorithm +// +// created on 2023-04-23 +// + +#include "img_algorithm.h" + + + +//{ +// "is-check-dog-ear": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "feeder", +// "visible": true, +// "field": "imgproc", +// "pos": 10, +// "ver": 1, +// "unit": "None", +// "title": "折角检测", +// "desc": "检测文稿是否存在折角", +// "type": "bool", +// "cur": false, +// "default": false, +// "size": 4 +// }, +// "dog-ear-size": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "feeder", +// "visible": true, +// "field": "imgproc", +// "pos": 11, +// "ver": 1, +// "unit": "None", +// "title": " 折角大小", +// "desc": "值越小,能检测到的折角越小", +// "type": "int", +// "cur": 70, +// "default": 70, +// "size": 4, +// "range": { +// "min": 0, +// "max": 100, +// "step": 1 +// }, +// "depend_or": ["is-check-dog-ear==true"] +// }, +// "dog-ear-size-outer": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "feeder", +// "visible": false, +// "field": "imgproc", +// "pos": 12, +// "ver": 1, +// "unit": "None", +// "title": " 折角大小(超出图片)", +// "desc": "值越小,能检测到的折角越小", +// "type": "int", +// "cur": 70, +// "default": 70, +// "size": 4, +// "range": { +// "min": 0, +// "max": 100, +// "step": 1 +// }, +// "depend_or": ["is-check-dog-ear==true"] +// }, +// "dog-ear-zoom-x": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "feeder", +// "visible": false, +// "field": "imgproc", +// "pos": 13, +// "ver": 1, +// "unit": "None", +// "title": "原图X轴缩放比例", +// "desc": "对于大尺寸图像而言通过zoom缩小图像可减少计算量。默认值1.0", +// "type": "float", +// "cur": 1.0, +// "default": 1.0, +// "size": 4, +// "range": [ +// "min": 0.1, +// "max": 4.0, +// "step": 0.5 +// ], +// "depend_or": ["is-check-dog-ear==true"] +// }, +// "dog-ear-zoom-y": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "feeder", +// "visible": false, +// "field": "imgproc", +// "pos": 14, +// "ver": 1, +// "unit": "None", +// "title": "原图y轴缩放比例", +// "desc": "对于大尺寸图像而言通过zoom缩小图像可减少计算量。默认值1.0", +// "type": "float", +// "cur": 1.0, +// "default": 1.0, +// "size": 4, +// "range": [ +// "min": 0.1, +// "max": 4.0, +// "step": 0.5 +// ], +// "depend_or": ["is-check-dog-ear==true"] +// }, +// "dog-ear-threashold": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "feeder", +// "visible": false, +// "field": "imgproc", +// "pos": 15, +// "ver": 1, +// "unit": "None", +// "title": "二值化阈值", +// "desc": "折角检测二值化参数", +// "type": "int", +// "cur": 40, +// "default": 40, +// "size": 4, +// "range": [ +// "min": 10, +// "max": 100, +// "step": 5 +// ], +// "depend_or": ["is-check-dog-ear==true"] +// }, +//} + +class CImageApplyDogEarDetection; +class gb_json; + +/// 二值化阈值 +/// 原图X轴缩放比例,对于大尺寸图像而言通过zoom缩小图像可减少计算量。默认值1.0(不缩放) +/// 原图Y轴缩放比例,对于大尺寸图像而言通过zoom缩小图像可减少计算量。默认值1.0(不缩放) +/// 理论顶点到实际轮廓最小距离的阈值(折角在图片内),大于该阈值则判定为折角,默认值50(像素) +/// 理论顶点到实际轮廓最小距离的阈值(折角超出图片),大于该阈值则判定为折角,默认值50(像素) +class dogear : public img_alg +{ + CImageApplyDogEarDetection* dog_; + gb_json* root_; + + std::string name_; + uint32_t pos_; + uint32_t ver_; + bool enable_; + + int threshold_; // dog-ear-threashold + double zoom_x_; // dog-ear-zoom-x + double zoom_y_; // dog-ear-zoom-y + int size_inner_; // dog-ear-size + int size_outer_; // dog-ear-size-outer + +public: + dogear(void); +protected: + ~dogear(); + +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; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + +public: + img_one_paper* execute(img_one_paper* img) override; + bool is_enabled(std::function get_opt_value) override; + + uint32_t position(void) override; + uint32_t version(void) override; + const char* option_name(void) override; +}; diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.cpp b/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.cpp new file mode 100644 index 0000000..df10937 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.cpp @@ -0,0 +1,511 @@ +#include "img_algorithm.h" + + +#include "dogear.h" +#include "common/json/gb_json.h" +#include "../capimage/hgutils.h" + +#ifdef TEMPORARY_API +extern int32_t (*set_dpi)(int*, int*); +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_one_paper +img_one_paper::img_one_paper() +{ +} +img_one_paper::~img_one_paper() +{ + clear(); +} + +void img_one_paper::clear(void) +{ + imgs_.clear(); +} + +int img_one_paper::init_from(void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel cc, img_status status, bool img_new, bool img_over) +{ + PACKIMAGE pk; + + memset(&pk, 0, sizeof(pk)); + pk.pos.new_img = img_new; + pk.pos.img_over = img_over; + pk.pos.paper_ind = paper_ind; + pk.pos.paper_side = side; + pk.pos.status = status; + pk.pos.channel_ind = cc; + pk.resolution_x = dpi_x; + pk.resolution_y = dpi_y; + if (cc == COLOR_CHANNEL_RGBA) + { + pk.width = w / 4; + pk.channels = 4; + } + else if (cc == COLOR_CHANNEL_RGB) + { + pk.width = w / 3; + pk.channels = 3; + } + else + { + pk.width = w; + pk.channels = 1; + } + pk.height = h; + + return init_from(data, w, h, &pk); +} +int img_one_paper::init_from(void* data, size_t w, size_t h, LPPACKIMAGE pimg) +{ + int ret = 0; + PROCIMG img; + + clear(); + memcpy(&img.head, pimg, sizeof(img.head)); + img.img = std::move(cv::Mat(h, w, CV_8UC1, data)); + imgs_.push_back(std::move(img)); + + return ret; +} +std::vector& img_one_paper::images_queue(void) +{ + return imgs_; +} + + + + + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_alg +img_alg::img_alg() : pos_(100), ver_(1), name_("") +{ +} +img_alg::~img_alg() +{ +} + +img_alg* img_alg::create_image_algorithm(img_alg_type type) +{ + if(type == IMG_ALG_DOGEAR) + return dynamic_cast(new dogear()); + if(type == IMG_ALG_ADJUST_DPI) + return dynamic_cast(new img_resizer()); + if(type == IMG_ALG_ADJUST_COLOR) + return dynamic_cast(new color_correct()); + + return nullptr; +} + +uint32_t img_alg::position(void) +{ + return pos_; +} +uint32_t img_alg::version(void) +{ + return ver_; +} +const char* img_alg::option_name(void) +{ + return name_.c_str(); +} + + + + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_resizer +// { +// "color-correct": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 100, +// "unit": "none", +// "ver": 1, +// "title": "颜色校正", +// "desc": "校正由于硬件特性产生的色偏,使图片颜色更接近真实", +// "type": "string", +// "cur": "普通模式", +// "default": "普通模式", +// "size": 20, +// "range": ["不校正", "普通模式", "增强模式"] +// } +// } +static std::string color_correct_json = + "{\"color-correct\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":100,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u989c\\u8272\\u6821\\u6b63\",\"desc\":\"\\u6821\\u6b63\\u7531\\u4e8e\\u786c\\u4ef6\\u7279\\u6027\\u4ea7\\u751f\\u7684\\u8272\\u504f\\uFF0C\\u4f7f\\u56fe\\u7247\\u989c\\u8272\\u66f4\\u63a5\\u8fd1\\u771f\\u5b9e\",\"type\":\"string\",\"cur\":\"\\u666e\\u901a\\u6a21\\u5f0f\",\"default\":\"\\u666e\\u901a\\u6a21\\u5f0f\",\"size\":20,\"range\":[\"\\u4e0d\\u6821\\u6b63\",\"\\u666e\\u901a\\u6a21\\u5f0f\",\"\\u589e\\u5f3a\\u6a21\\u5f0f\"]}}"; + +color_correct::color_correct() : enable_(true), enhance_(false) +{ + name_ = "color-correct"; + cfg_ = new gb_json(); + cfg_->attach_text(&color_correct_json[0]); + + gb_json* child = nullptr; + + if(cfg_->get_value(name_.c_str(), child) && child) + { + std::string val(""); + + child->get_value("cur", val); + on_cur_val_changed(val); + child->get_value("ver", ver_); + child->get_value("pos", pos_); + child->release(); + } +} +color_correct::~color_correct() +{ + cfg_->release(); +} + +void color_correct::on_cur_val_changed(std::string& val) +{ + enable_ = val != "\xE4\xB8\x8D\xE6\xA0\xA1\xE6\xAD\xA3"; + enhance_ = val == "\xE5\xA2\x9E\xE5\xBC\xBA\xE6\xA8\xA1\xE5\xBC\x8F"; +} + +int32_t color_correct::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + if(cfg_name) + return inner_get_config(cfg_, buf, len, cfg_name, strval); + else + { + std::string val(cfg_->to_string()); + + if(*len < val.length()) + { + *len = val.length() + 4; + if(strval) + *strval = std::move(val); + + return ENOMEM; + } + + memcpy(buf, val.c_str(), val.length()); + *len = val.length(); + + return 0; + } +} +int32_t color_correct::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + gb_json *child = nullptr; + int32_t ret = ENOENT; + + if(cfg_->get_value(cfg_name, child) && child) + { + sane_cfg_provider::sane_refine_range(child, data, len); + if(name_ == cfg_name) + { + std::string val((char*)data); + + on_cur_val_changed(val); + child->set_value("cur", val.c_str()); + child->release(); + } + } + + return ret; +} +void color_correct::update_enabled(std::function get_opt) +{} +int32_t color_correct::get_value(const char* name, const char* key, std::string& val) +{ + gb_json *child = nullptr; + int32_t ret = ENOENT; + + if(cfg_->get_value(name, child) && child) + { + sane_cfg_provider::raw_value_in_json(child, key, val); + child->release(); + } + + return ret; +} +img_one_paper* color_correct::execute(img_one_paper* img) +{ + if(enable_) + { + + for(auto& v: img->images_queue()) + { + correctColor(v.img, enhance_); + } + } + img->add_ref(); + + return img; +} +bool color_correct::is_enabled(std::function get_opt_value) +{ + return enable_; +} + + + + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_resizer +// { +// "resolution": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "Common", +// "pos": 0, +// "unit": "DPI", +// "ver": 1, +// "title": "分辨率", +// "desc": "设置扫描图像的分辨率", +// "type": "int", +// "cur": 200, +// "default": 200, +// "size": 4, +// "range": { +// "min": 100, +// "max": 600, +// "step": 50 +// } +// } +// } +static std::string resize_json = + "{\"resolution\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"CIS\",\"pos\":200,\"unit\":\"DPI\",\"ver\":1,\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":{\"min\":100,\"max\":600,\"step\":50}}}"; + +img_resizer::img_resizer() : dpi_(200), enable_(false) +{ + name_ = "resolution"; + cfg_ = new gb_json(); + cfg_->attach_text(&resize_json[0]); + + gb_json* child = nullptr; + + if(cfg_->get_value(name_.c_str(), child) && child) + { + child->get_value("cur", dpi_); + child->get_value("ver", ver_); + child->get_value("pos", pos_); + child->release(); + } +} +img_resizer::~img_resizer() +{ + cfg_->release(); +} + +int32_t img_resizer::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + if(cfg_name) + return inner_get_config(cfg_, buf, len, cfg_name, strval); + else + { + std::string val(cfg_->to_string()); + + if(*len < val.length()) + { + *len = val.length() + 4; + if(strval) + *strval = std::move(val); + + return ENOMEM; + } + + memcpy(buf, val.c_str(), val.length()); + *len = val.length(); + + return 0; + } +} +int32_t img_resizer::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + gb_json *child = nullptr; + int32_t ret = ENOENT; + + if(cfg_->get_value(cfg_name, child) && child) + { + sane_cfg_provider::sane_refine_range(child, data, len); + if(name_ == cfg_name) + { + dpi_ = *(int*)data; + child->set_value("cur", dpi_); + child->release(); + + int x = *(int*)data, + y = x; + set_dpi(&x, &y); + enable_ = x != dpi_ || y != dpi_; + } + } + + return ret; +} +void img_resizer::update_enabled(std::function get_opt) +{} +int32_t img_resizer::get_value(const char* name, const char* key, std::string& val) +{ + gb_json *child = nullptr; + int32_t ret = ENOENT; + + if(cfg_->get_value(name, child) && child) + { + sane_cfg_provider::raw_value_in_json(child, key, val); + child->release(); + } + + return ret; +} +img_one_paper* img_resizer::execute(img_one_paper* img) +{ + if(enable_) + { + + for(auto& v: img->images_queue()) + { + double ratio_x = dpi_ * 1.0f / v.head.resolution_x, + ratio_y = dpi_ * 1.0f / v.head.resolution_y; + cv::resize(v.img, v.img, cv::Size(0,0), ratio_x, ratio_y); + } + } + img->add_ref(); + + return img; +} +bool img_resizer::is_enabled(std::function get_opt_value) +{ + return enable_; +} + + + + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_alg +// { +// "img-format": { +// "category": "base", +// "readonly": true, +// "affect": 0, +// "group": "output", +// "visible": true, +// "field": "Common", +// "pos": 0, +// "unit": "None", +// "title": "图片格式", +// "desc": "设备输出的图片文件格式", +// "type": "string", +// "cur": "JPEG", +// "default": "JPEG", +// "size": 20, +// "ver": 1, +// "range": ["JPEG", "PNG", "TIFF"] +// } +// } +static std::string fmt_json = + "{\"img-format\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"output\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u56fe\\u7247\\u683c\\u5f0f\",\"desc\":\"\\u8bbe\\u5907\\u8f93\\u51fa\\u7684\\u56fe\\u7247\\u6587\\u4ef6\\u683c\\u5f0f\",\"type\":\"string\",\"cur\":\"JPEG\",\"default\":\"JPEG\",\"size\":20,\"ver\":1,\"range\":[\"JPEG\",\"PNG\",\"TIFF\"]}}"; + +img_encoder::img_encoder() : fmt_("JPEG") +{ + cfg_ = new gb_json(); + if(cfg_->attach_text(&fmt_json[0])) + { + gb_json* child = nullptr; + cfg_->get_value("img-format", child); + if(child) + { + child->get_value("cur", fmt_); + child->release(); + } + } +} +img_encoder::~img_encoder() +{} + +int32_t img_encoder::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + int32_t ret = ENOENT; + + if(cfg_name) + { + ret = inner_get_config(cfg_, buf, len, cfg_name, strval); + } + else + { + std::string val(cfg_->to_string()); + + if(*len < val.length()) + { + *len = val.length() + 4; + ret = ENOMEM; + } + else + { + memcpy(buf, val.c_str(), val.length()); + *len = val.length(); + ret = 0; + } + } + + return ret; +} +int32_t img_encoder::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + gb_json* child = nullptr; + int32_t ret = ENOENT; + + if(cfg_->get_value(cfg_name, child) && child) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + if(afterdo) + { + int v = 0; + child->get_value("affect", v); + *afterdo = v; + } + child->release(); + + if(strcmp(cfg_name, "img-format") == 0) + fmt_ = std::string((char*)data, *len); + } + + return ret; +} +void img_encoder::update_enabled(std::function get_opt) +{} +int32_t img_encoder::get_value(const char* name, const char* key, std::string& val) +{ + gb_json* child = nullptr; + int32_t ret = ENOENT; + + if(cfg_->get_value(name, child) && child) + { + val = std::move(sane_cfg_provider::sane_option_value_get(child, key)); + child->release(); + ret = val.empty() ? ENOENT : 0; + } + + return ret; +} + +#include "imageencode.h" + +MemoryPtr img_encoder::encode(PROCIMG* img) +{ + JpegImageEncode encoder(fmt_.c_str(), img->head.resolution_x); + + if(fmt_ == "JPEG") + img->head.format = IMG_FMT_JPEG; + else if(fmt_ == "PNG") + img->head.format = IMG_FMT_PNG; + else if(fmt_ == "TIFF") + img->head.format = IMG_FMT_TIFF; + + return encoder.encode(img->img); +} diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.h b/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.h new file mode 100644 index 0000000..5d74563 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.h @@ -0,0 +1,180 @@ +#pragma once + +// base definition for image algorithm +// +// created on 2023-04-18 +// + +#include +#include + + +//{ +// "multiout-type": { +// "category": "base", +// "readonly" : false, +// "affect" : 4, +// "group" : "base", +// "visible" : true, +// "field" : "ImageProc", +// "pos" : 900, +// "unit" : "None", +// "title" : "多流输出类型", +// "desc" : "选择多流输出的类型", +// "type" : "string", +// "cur" : "彩色+灰度+黑白", +// "default" : "彩色+灰度+黑白", +// "size" : 32, +// "range" : ["彩色+灰度+黑白", "彩色+灰度", "彩色+黑白", "灰度+黑白"] , +// "depend_or" : ["is-multiout==true"] +// } +//} +// +// - component exports: +// +// img_processor* load_img_processor(parameter_get*) +// void apply_img_proc(dyn_mem_ptr) +#include "imageprocess/ImageApply.h" +#include "imemory.h" +#include "common/sane_cfg.h" + +class gb_json; + +class img_one_paper : public refer +{ + std::vector imgs_; + + void clear(void); + +public: + img_one_paper(); + +protected: + ~img_one_paper(); + +public: + int init_from(void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side = PAPER_SIDE_LEFT, clr_channel cc = COLOR_CHANNEL_RGB, img_status status = IMG_STATUS_OK, bool img_new = true, bool img_over = true); + int init_from(void* data, size_t w, size_t h, LPPACKIMAGE pimg); + + std::vector& images_queue(void); +}; + +enum img_alg_type +{ + IMG_ALG_NONE = 0, + IMG_ALG_DOGEAR, + IMG_ALG_SIZE_CHECK, + IMG_ALG_FILL_HOLE, + IMG_ALG_AUTO_CROP, + IMG_ALG_BLANK, + IMG_ALG_CUSTOM_AREA, + IMG_ALG_FADE_BACK, + IMG_ALG_FILTER, + IMG_ALG_ADJUST_COLOR, + IMG_ALG_HSV_CORRECT, + IMG_ALG_REFUSE_INFLOW, + IMG_ALG_AUTO_CONTRAST, + IMG_ALG_TEXTURE_REMOVE, + IMG_ALG_SHARPEN, + IMG_ALG_ADJUST_DPI, + IMG_ALG_BW, + IMG_ALG_DETACH_NOISE, + IMG_ALG_CONCATEN, + IMG_ALG_ROTATE, +}; + +class img_alg : public sane_cfg_provider +{ +protected: + int pos_; + int ver_; + std::string name_; + +public: + img_alg(); + + static img_alg* create_image_algorithm(img_alg_type type); + +protected: + virtual ~img_alg(); + +public: + // return: 0 - success + // EINVAL - the algorithm apply to the image failed, result set into PACKIMAGE::pos::status + virtual img_one_paper* execute(img_one_paper* img) = 0; + virtual bool is_enabled(std::function get_opt_value) = 0; + + virtual uint32_t position(void); + virtual uint32_t version(void); + virtual const char* option_name(void); +}; + + +class color_correct : public img_alg +{ + gb_json* cfg_; + bool enable_; + bool enhance_; + + void on_cur_val_changed(std::string& val); + +public: + color_correct(); +protected: + ~color_correct(); + +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; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + +public: + virtual img_one_paper* execute(img_one_paper* img) override; + virtual bool is_enabled(std::function get_opt_value) override; +}; + + +class img_resizer : public img_alg +{ + gb_json* cfg_; + int dpi_; + bool enable_; + +public: + img_resizer(); +protected: + ~img_resizer(); + +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; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + +public: + virtual img_one_paper* execute(img_one_paper* img) override; + virtual bool is_enabled(std::function get_opt_value) override; +}; + + +class img_encoder : public sane_cfg_provider +{ + std::string fmt_; + gb_json* cfg_; + +public: + img_encoder(); +protected: + ~img_encoder(); + +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; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + +public: + MemoryPtr encode(PROCIMG* img); +}; + diff --git a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp new file mode 100644 index 0000000..82ec64a --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp @@ -0,0 +1,316 @@ +#include "cis_preproc.h" + + +#include "common/json/gb_json.h" + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// configuration text +// +//{ +// "montage": { +// "category": "base", +// "readonly" : false, +// "affect" : 3, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "val": 1, +// "pos" : 10, +// "unit" : "None", +// "title" : "ͼ��ƴ��", +// "desc" : "��CIS�ɼ���ԭʼ���ݻָ�Ϊ������ͼ��", +// "type" : "bool", +// "cur" : true, +// "default" : true, +// "size" : 4 +// }, +// "fb-split": { +// "category": "base", +// "readonly" : false, +// "affect" : 2, +// "group" : "base", +// "visible" : false, +// "field" : "cis", +// "val": 1, +// "pos" : 20, +// "unit" : "None", +// "title" : "���������", +// "desc" : "��������ϳɵ�һ��ͼƬ����ֳ�����ͷ���ͼƬ", +// "type" : "bool", +// "cur" : true, +// "default" : true, +// "size" : 4, +// "depend_and": ["montage==true"] +// } +//} + +static std::string g_cis_cfg("{\"montage\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":10,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u56fe\\u50cf\\u62fc\\u63a5\",\"desc\":\"\\u5c06CIS\\u91c7\\u96c6\\u7684\\u539f\\u59cb\\u6570\\u636e\\u6062\\u590d\\u4e3a\\u6b63\\u5e38\\u7684\\u56fe\\u50cf\",\"type\":\"bool\",\"cur\":true,\"default\":true,\"size\":4},\"fb-split\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":20,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u62c6\\u5206\\u6b63\\u53cd\\u9762\",\"desc\":\"\\u5c06\\u6b63\\u53cd\\u9762\\u5408\\u6210\\u7684\\u4e00\\u5f20\\u56fe\\u7247\\u62c6\\u5206\\u6210\\u6b63\\u9762\\u548c\\u53cd\\u9762\\u56fe\\u7247\",\"type\":\"bool\",\"cur\":true,\"default\":true,\"size\":4}}"); + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class cis_pre_do +#ifdef TEMPORARY_API +#include "../capimage/hgutils.h" + +img_one_paper* cis_montager(img_one_paper* in) +{ + for(auto& v: in->images_queue()) + { + // 0x00090002 GetMergeMat(int dstwidth ,int dstheight,int type,cv::Mat& mat,unsigned int fpgaversion) + v.img = GetMergeMat(v.head.width * v.head.channels, v.head.height, v.head.channels == 1 ? CV_8UC1 : CV_8UC3, v.img, 0x00090001); + v.head.width = v.img.cols; + v.head.height = v.img.rows; + } + in->add_ref(); + + return in; +} +img_one_paper* cis_spliter(img_one_paper* in) +{ + std::vector result; + + for(auto& v: in->images_queue()) + { + if(v.head.pos.paper_side == PAPER_SIDE_LEFT) + { + int actwidth = v.img.cols / 2; + int actheight = v.img.rows; + for (int i = 0; i < 2; i++) + { + PROCIMG ii; + ii.img = v.img(cv::Rect(i * actwidth, 0, actwidth, actheight)); + if (!ii.img.empty()) + { + memcpy(&ii.head, &v.head, sizeof(ii.head)); + ii.head.width = v.img.cols; + ii.head.height = v.img.rows; + ii.head.pos.paper_side = i == 0 ? PAPER_SIDE_FRONT : PAPER_SIDE_BACK; + + result.push_back(ii); + } + } + } + } + if(result.size()) + in->images_queue() = std::move(result); + + in->add_ref(); + + return in; +} + +#endif + +cis_pre_do::cis_pre_do(std::function montage + , std::function< img_one_paper* (img_one_paper*)> split) + : montage_(montage), split_(split) + , cfg_(g_cis_cfg), is_montage_(true), is_split_(true) +{ + if (!montage_) + montage_ = cis_montager; + if (!split_) + split_ = cis_spliter; + + init_value(); +} +cis_pre_do::~cis_pre_do() +{} + +gb_json* cis_pre_do::from_json_text(char* jsn_text) +{ + gb_json* jsn = new gb_json(); + + if (!jsn_text) + jsn_text = &cfg_[0]; + + if (!jsn->attach_text(jsn_text)) + { + jsn->release(); + jsn = nullptr; + } + + return jsn; +} +void cis_pre_do::init_value(void) +{ + gb_json* jsn = from_json_text(&cfg_[0]); + + if (jsn) + { + gb_json* child = nullptr; + + if (jsn->get_value("montage", child) && child) + { + if (!child->get_value("cur", is_montage_)) + is_montage_ = true; + child->release(); + } + if (jsn->get_value("fb-split", child) && child) + { + if (!child->get_value("cur", is_split_)) + is_split_ = true; + child->release(); + } + jsn->release(); + } +} + +int32_t cis_pre_do::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + gb_json* jsn = from_json_text(&cfg_[0]); + int ret = ENOENT; + + if (jsn) + { + ret = inner_get_config(jsn, buf, len, cfg_name, strval); + jsn->release(); + } + + return ret; +} +int32_t cis_pre_do::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + int ret = ENOENT; + gb_json* root = from_json_text(), *child = nullptr; + + if (root) + { + if (root->get_value(cfg_name, child) && child) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + if(afterdo) + { + int v = 0; + child->get_value("affect", v); + *afterdo = v; + } + child->release(); + cfg_ = root->to_string(); + init_value(); + } + + root->release(); + } + + return ret; +} +void cis_pre_do::update_enabled(std::function get_opt) +{ + gb_json* root = new gb_json(); + + if(root->attach_text(&cfg_[0])) + { + sane_cfg_provider::update_option_enable_status(root, get_opt); + cfg_ = std::move(root->to_string()); + } + + root->release(); +} +int32_t cis_pre_do::get_value(const char* name, const char* key, std::string& val) +{ + gb_json* root = new gb_json(), *child = nullptr; + int32_t ret = ENOENT; + + if(root->attach_text(&cfg_[0])) + { + if(root->get_value(name, child) && child) + { + if(sane_cfg_provider::raw_value_in_json(child, key, val)) + ret = 0; + child->release(); + } + } + root->release(); + + return ret; +} + +img_one_paper* cis_pre_do::execute(img_one_paper* img) +{ + img->add_ref(); + + if(is_montage_) + { + printf("montage ...\n"); + img_one_paper* mont = montage_(img); + img->release(); + img = mont; + } + if(is_split_) + { + printf("split ...\n"); + img_one_paper* sp = split_(img); + img->release(); + img = sp; + } + + return img; +} + +// void cis_pre_do::pre_do(std::function put, void* data, size_t w, size_t h, size_t paper_ind, img_status status, bool img_new, bool img_over) +// { +// img_one_paper* img = new img_one_paper(); +// PACKIMAGE pkimg; + +// memset(&pkimg, 0, sizeof(pkimg)); +// pkimg.pos.new_img = img_new; +// pkimg.pos.img_over = img_over; +// pkimg.pos.paper_ind = paper_ind; +// pkimg.pos.paper_side = side_; +// pkimg.pos.status = status; +// pkimg.resolution_x = dpi_x_; +// pkimg.resolution_y = dpi_y_; +// if (clr_ == COLOR_CHANNEL_RGBA) +// pkimg.channels = 4; +// else if (clr_ == COLOR_CHANNEL_RGB) +// pkimg.channels = 3; +// else +// pkimg.channels = 1; +// pkimg.bpp = 8; +// pkimg.data_size = w * h; +// pkimg.format = IMG_FMT_BMP; +// pkimg.width = w / pkimg.channels; +// pkimg.height = h; +// pkimg.bppc = pkimg.channels * pkimg.bpp; +// if (img->init_from(data, w, h, &pkimg) == 0) +// { +// std::vector imgs; + +// if (is_montage_) +// { +// // do montage ... +// img_one_paper* mont = montage_(img); + +// img->release(); +// img = nullptr; + +// // split ? +// if (is_split_) +// { +// img_one_paper* back = nullptr, +// *front = split_(mont, &back); +// mont->release(); +// imgs.push_back(front); +// imgs.push_back(back); +// } +// else +// imgs.push_back(mont); +// } +// else +// { +// imgs.push_back(img); +// img = nullptr; +// } + +// for (auto& v : imgs) +// { +// put(v); +// v->release(); +// } +// imgs.clear(); +// } + +// if(img) +// img->release(); +// } diff --git a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h new file mode 100644 index 0000000..5d6cb0f --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h @@ -0,0 +1,40 @@ +#pragma once + +// CIS pre-processor, to transform raw data from CIS to front & back image +// +// created on 2023-04-18 +// + +#include "./algs/img_algorithm.h" +#include + +class gb_json; + +class cis_pre_do : public sane_cfg_provider +{ + std::string cfg_; + bool is_montage_; + bool is_split_; + + std::function montage_; + std::function split_; + + gb_json* from_json_text(char* jsn_text = nullptr); + void init_value(void); + +public: + cis_pre_do(std::function montage = std::function() + , std::function split = std::function()); + +protected: + ~cis_pre_do(); + +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; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + +public: + img_one_paper* execute(img_one_paper* img); +}; diff --git a/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp b/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp new file mode 100644 index 0000000..0e570e3 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp @@ -0,0 +1,388 @@ +#include "img_process.h" + +#include +#include "common/json/gb_json.h" +#include "img_process/algs/img_algorithm.h" + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// + + + + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_processor + +img_processor::img_processor(std::function img_sender + , std::function get_opt) + : img_sender_(img_sender), get_opt_val_(get_opt), speed_first_(true), run_(true) + , scan_staus_(0), busy_cnt_(0) +{ + cis_pre_ = new cis_pre_do(); + encoder_ = new img_encoder(); + + load_processors(); + worker_ = new thread_pool(this); + worker_->thread_new(&img_processor::worker_thread, true); +} +img_processor::~img_processor() +{ + stop(); + worker_->thread_stop(); + worker_->release(); + cis_pre_->release(); + encoder_->release(); + + clear_processors(); +} + + bool img_processor::compare_img_processors_position(img_alg* l, img_alg* r) + { + return l->position() < r->position(); + } + +void img_processor::add_to_json(gb_json* root, sane_cfg_provider* cfg, void** buf, size_t* len) +{ + size_t l = *len; + char* mem = (char*)*buf; + int32_t ret = cfg->get_config(mem, &l); + + if(ret == ENOMEM) + { + l += 31; + l /= 16; + l *= 16; + delete[] mem; + mem = new char[l]; + memset(mem, 0, l); + + *len = l; + *buf = mem; + ret = cfg->get_config(mem, &l); + } + + if(ret == 0) + { + gb_json* jsn = new gb_json(), *child = nullptr; + if(jsn->attach_text(mem)) + { + child = jsn->first_child(); + while(child) + { + root->set_value(child->key().c_str(), child); + child->release(); + child = jsn->next_child(); + } + } + jsn->release(); + } +} +void img_processor::clear_processors(void) +{ + for(auto& v: all_proc_) + v->release(); + all_proc_.clear(); + + for(auto& v: cur_proc_) + v->release(); + cur_proc_.clear(); +} +void img_processor::load_processors(void) +{ + img_alg* alg = nullptr; + + clear_processors(); + +#define CREATE_ALG(type) \ + alg = img_alg::create_image_algorithm(type); \ + if(alg) \ + all_proc_.push_back(alg); + + CREATE_ALG(IMG_ALG_DOGEAR); + CREATE_ALG(IMG_ALG_SIZE_CHECK); + CREATE_ALG(IMG_ALG_FILL_HOLE); + CREATE_ALG(IMG_ALG_AUTO_CROP); + CREATE_ALG(IMG_ALG_BLANK); + CREATE_ALG(IMG_ALG_CUSTOM_AREA); + CREATE_ALG(IMG_ALG_FADE_BACK); + CREATE_ALG(IMG_ALG_FILTER); + CREATE_ALG(IMG_ALG_ADJUST_COLOR); + CREATE_ALG(IMG_ALG_HSV_CORRECT); + CREATE_ALG(IMG_ALG_REFUSE_INFLOW); + CREATE_ALG(IMG_ALG_AUTO_CONTRAST); + CREATE_ALG(IMG_ALG_TEXTURE_REMOVE); + CREATE_ALG(IMG_ALG_SHARPEN); + CREATE_ALG(IMG_ALG_ADJUST_DPI); + CREATE_ALG(IMG_ALG_BW); + CREATE_ALG(IMG_ALG_DETACH_NOISE); + CREATE_ALG(IMG_ALG_CONCATEN); + CREATE_ALG(IMG_ALG_ROTATE); + + reorder_processors(); +} +void img_processor::reorder_processors(void) +{ + // first, discard lower version of the same option name ... + for(int i = 0; i < (int)all_proc_.size() - 1; ++i) + { + for(int j = i + 1; j < (int)all_proc_.size(); ++j) + { + if(strcmp(all_proc_[i]->option_name(), all_proc_[j]->option_name()) == 0) + { + if(all_proc_[i]->version() < all_proc_[j]->version()) + { + all_proc_[i]->release(); + all_proc_[i] = all_proc_[j]; + } + else + { + all_proc_[j]->release(); + } + all_proc_.erase(all_proc_.begin() + j); + j--; + } + } + } + + // last, push active processors + reload_cur_processors(); +} +void img_processor::reload_cur_processors(void) +{ + for(auto& v: cur_proc_) + v->release(); + cur_proc_.clear(); + + for(auto& v : all_proc_) + { + if(v->is_enabled(get_opt_val_)) + { + v->add_ref(); + cur_proc_.push_back(v); + } + } + + std::sort(cur_proc_.begin(), cur_proc_.end(), img_processor::compare_img_processors_position); +} + +uint32_t img_processor::add_busy_count(int adden) +{ + std::lock_guard lock(cnt_lock_); + + busy_cnt_ += adden; + + return busy_cnt_; +} +void img_processor::worker_thread(bool first) +{ + while(run_) + { + if(!first && !speed_first_) + { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + continue; + } + + img_one_paper* img = nullptr; + if(img_que_.take(img, true)) + { + if(img) + { + add_busy_count(); + handle_image(img); + add_busy_count(-1); + + // img->release(); // release in 'handle_image' + } + else + { + while(add_busy_count(0)) + std::this_thread::sleep_for(std::chrono::microseconds(50)); + + img_sender_(nullptr, nullptr, nullptr, scan_staus_); + } + } + } +} +void img_processor::handle_image(img_one_paper* img) +{ + img_one_paper* doing = nullptr; + + // img->add_ref(); // release it right now + + // CIS pre-do ... + doing = cis_pre_->execute(img); + img->release(); + img = doing; + + // image process ... + for(auto& v: cur_proc_) + { + doing = v->execute(img); + + img->release(); + img = doing; + } + + // encode/compress ... + for(auto& v: img->images_queue()) + { + MemoryPtr imgf = encoder_->encode(&v); + + img_sender_(&v.head, imgf, v.info.c_str(), v.info.length()); + } + img->release(); +} + +int32_t img_processor::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + int32_t ret = 0; + + if (!len) + return EINVAL; + + if (cfg_name) + { + ret = cis_pre_->get_config(buf, len, cfg_name, strval); + if(ret == ENOENT) + { ret = encoder_->get_config(buf, len, cfg_name, strval); + if(ret == ENOENT) + { + for(auto& v : all_proc_) + { + ret = v->get_config(buf, len, cfg_name, strval); + if(ret != ENOENT) + break; + } + } + } + } + else + { + gb_json* root = new gb_json("{}"); + size_t size = 2 * 1024, + bufl = size; + char* mem = new char[size]; + std::string val(""); + + add_to_json(root, dynamic_cast(cis_pre_), (void**)&mem, &bufl); + for(auto& v: all_proc_) + add_to_json(root, dynamic_cast(v), (void**)&mem, &bufl); + add_to_json(root, dynamic_cast(encoder_), (void**)&mem, &bufl); + + val = root->to_string(); + root->release(); + delete[] mem; + { + if (*len < val.length()) + { + *len = val.length() + 4; + ret = ENOMEM; + } + else + { + memcpy(buf, val.c_str(), val.length()); + *len = val.length(); + } + } + } + + return ret; +} +int32_t img_processor::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + int ret = cis_pre_->set_config(cfg_name, data, len, afterdo); + + if(ret == ENOENT) + { + ret = encoder_->set_config(cfg_name, data, len, afterdo); + if(ret == ENOENT) + { + for(auto& v: all_proc_) + { + ret = v->set_config(cfg_name, data, len, afterdo); + if(ret != ENOENT) + { + reload_cur_processors(); + break; + } + } + } + } + + return ret; +} +void img_processor::update_enabled(std::function get_opt) +{ + // sane_cfg_provider::update_option_enable_status(cfg_, get_opt); + cis_pre_->update_enabled(get_opt); + for(auto& v: all_proc_) + { + v->update_enabled(get_opt); + } + reload_cur_processors(); + encoder_->update_enabled(get_opt); +} +int32_t img_processor::get_value(const char* name, const char* key, std::string& val) +{ + int32_t ret = cis_pre_->get_value(name, key, val); + + if(ret == ENOENT) + { + ret = encoder_->get_value(name, key, val); + if(ret == ENOENT) + { + for(auto& v: all_proc_) + { + ret = v->get_value(name, key, val); + if(ret != ENOENT) + break; + } + } + } + + return ret; +} + +int32_t img_processor::push_image(img_one_paper* img, bool over) +{ + if(run_) + { + if(over) + { + scan_staus_ = (uint32_t)(uint64_t)img; + img_que_.save(nullptr, true); + } + else + { + img->add_ref(); + + size_t cnt = img_que_.save(img, true); + + if(speed_first_ && cnt >= 4 && worker_->count() < 3) + worker_->thread_new(&img_processor::worker_thread, false); + } + } + + return 0; +} +int32_t img_processor::stop(void) +{ + run_ = false; + for(size_t i = 0; i < worker_->count(); ++i) + img_que_.quit(); + + return 0; +} +int32_t img_processor::set_speed_first(bool first) +{ + speed_first_ = first; + + return 0; +} +int32_t img_processor::que_size(void) +{ + return img_que_.size(); +} diff --git a/device/gxx-linux/usb/src/async_model/img_process/img_process.h b/device/gxx-linux/usb/src/async_model/img_process/img_process.h new file mode 100644 index 0000000..e4f42a1 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/img_process.h @@ -0,0 +1,74 @@ +#pragma once + +// image process interface classes +// +// created on 2022-12-14 +// + +#include "common/referer.h" +#include "common/packet.h" +#include "common/sane_cfg.h" +#include "cis_preproc.h" +#include "common/ipc_util.h" +#include +#include +#include "imemory.h" + +#define IMG_SENDER_PROTO void(LPPACKIMAGE /*image head, nullptr for scan over*/, MemoryPtr /*image data, nullptr for scan over*/, const void* /*image info*/, size_t/*image info bytes, scanner status for scan over*/) + +class img_alg; +class img_encoder; +class cis_pre_do; +class gb_json; + +class img_processor : public sane_cfg_provider +{ + std::function img_sender_; + std::function get_opt_val_; + + std::vector all_proc_; + + cis_pre_do* cis_pre_; + std::vector cur_proc_; + img_encoder* encoder_; + + safe_fifo img_que_; + thread_pool* worker_; + volatile bool speed_first_; + volatile bool run_; + uint32_t scan_staus_; + uint32_t busy_cnt_; + std::mutex cnt_lock_; + + static bool compare_img_processors_position(img_alg* l, img_alg* r); + + void add_to_json(gb_json* root, sane_cfg_provider* cfg, void** buf, size_t* len); + void clear_processors(void); + void load_processors(void); + void reorder_processors(void); + void reload_cur_processors(void); + + uint32_t add_busy_count(int adden = 1); + void worker_thread(bool first); + void handle_image(img_one_paper* img); + +public: + img_processor(std::function img_sender, std::function get_opt); + +protected: + ~img_processor(); + + // 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; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + +public: + int32_t push_image(img_one_paper* img/*scan status if 'over' was true*/, bool over = false); + int32_t stop(void); + int32_t set_speed_first(bool first); // start as many threads as possible if 'first' was true, or down to ONE thread + int32_t que_size(void); +}; + diff --git a/device/gxx-linux/usb/src/common/data.cpp b/device/gxx-linux/usb/src/async_model/io/data.cpp similarity index 99% rename from device/gxx-linux/usb/src/common/data.cpp rename to device/gxx-linux/usb/src/async_model/io/data.cpp index 3a8f2d1..5fa5ec4 100644 --- a/device/gxx-linux/usb/src/common/data.cpp +++ b/device/gxx-linux/usb/src/async_model/io/data.cpp @@ -43,7 +43,7 @@ namespace sys_util } } #else -#include "sys_util.h" +#include "common/sys_util.h" #include #include #endif diff --git a/device/gxx-linux/usb/src/common/data.h b/device/gxx-linux/usb/src/async_model/io/data.h similarity index 94% rename from device/gxx-linux/usb/src/common/data.h rename to device/gxx-linux/usb/src/async_model/io/data.h index 993de72..6ec9e89 100644 --- a/device/gxx-linux/usb/src/common/data.h +++ b/device/gxx-linux/usb/src/async_model/io/data.h @@ -4,8 +4,8 @@ // // created on 2023-03-10 -#include "referer.h" -#include "packet.h" +#include "common/referer.h" +#include "common/packet.h" #include #include @@ -13,12 +13,11 @@ #define CLS_PTR(cls) typedef cls* cls##_ptr; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // /* packet parameter keeper, parameter of corresponding packet */ -#define PROGRESS_NOTIFYER std::function +#define PROGRESS_NOTIFYER std::function class packet_data_base : public refer { @@ -215,7 +214,7 @@ CLS_PTR(file_reader); // // dyn_mem_ptr - the packet buffer, read-only // -// uint32_t* - to return how many data in bytes the handler consumed +// uint32_t* - to return how many data in bytes the handler consumed, the most high bit is to indicate whether should notify the returned packet has sent // // normally, the value should be sizeof(PACK_BASE) + PACK_BASE::payload_len, i.e. the handler consume all data of an entire packet // @@ -229,5 +228,7 @@ CLS_PTR(file_reader); // // return value of all routines is the reply packet, nullptr if the packet need not reply // +// NOTE: when parameter uint32_t* and packet_data_base_ptr* both are nullptr, it is notifying the command reply packet has sent, callback should return nullptr only +// #define FUNCTION_PROTO_COMMAND_HANDLE dyn_mem_ptr(dyn_mem_ptr, uint32_t* /*used*/, packet_data_base_ptr* /*The number of bytes required for this packet, 0 is over for this packet*/) diff --git a/device/gxx-linux/usb/src/async_model/io/sent_img.cpp b/device/gxx-linux/usb/src/async_model/io/sent_img.cpp new file mode 100644 index 0000000..4e27051 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/io/sent_img.cpp @@ -0,0 +1,110 @@ +#include "sent_img.h" + +#include "common/sys_util.h" +#include "common/log_util.h" + +// C2-B0-AF-79-75-D6 +// + + +image_packet::image_packet(LPPACKIMAGE head, MemoryPtr img, uint32_t scanid, uint32_t sn, const void* info, size_t info_size) + : img_(img), offset_(0), sn_(sn), info_over_(false) +{ + LPPACK_BASE pack = nullptr; + LPPACKIMAGE pimg = nullptr; + + if(info && info_size) + info_ = std::string((const char*)info, info_size); + else + info_ = ""; + + head_ = dyn_mem::memory(sizeof(PACK_BASE) + sizeof(PACKIMAGE)); + pack = (LPPACK_BASE)head_->ptr(); + pimg = (LPPACKIMAGE)pack->payload; + BASE_PACKET_REPLY(*pack, PACK_CMD_SCAN_IMG_ROGER, scanid, 0); + pack->payload_len = sizeof(PACKIMAGE); + + memcpy(pimg, head, sizeof(*pimg)); + pimg->data_size = img->size(); + pimg->info_size = info_size; + + head_->set_len(sizeof(PACK_BASE) + sizeof(PACKIMAGE)); + info_over_ = info_.empty(); + + log_cls::log(LOG_LEVEL_ALL, "Image-%04u wait to be sent: size = %u\n", sn_, img->size() + info_.length()); +} +image_packet::~image_packet() +{ + uint32_t size = img_->size(); + + head_->release(); + img_.reset(); + log_cls::log(LOG_LEVEL_ALL, "Image-%04u sending complete: %u/%u\n", sn_, offset_, size); +} + +bool image_packet::is_memory_block(void) +{ + return false; +} +uint32_t image_packet::get_rest(void) +{ + return head_->get_rest() + info_.length() + img_->size() - offset_; +} + +// following API valid when is_memory_block() return true +uint8_t* image_packet::ptr(void) +{ + return nullptr; +} + +// following API valid when is_memory_block() return false. return error code +int image_packet::fetch_data(void* buf, uint32_t* size) +{ + if(head_->get_rest()) + { + if(*size < head_->get_rest()) + { + memcpy(buf, head_->ptr(), *size); + } + else + { + memcpy(buf, head_->ptr(), head_->get_rest()); + *size = head_->get_rest(); + } + head_->used(*size); + } + else if(!info_over_) + { + if(*size < info_.length() - offset_) + { + memcpy(buf, info_.c_str() + offset_, *size); + offset_ += *size; + } + else + { + memcpy(buf, info_.c_str() + offset_, info_.length() - offset_); + *size = info_.length() - offset_; + + info_over_ = true; + info_ = ""; + offset_ = 0; + } + } + else + { + if(*size + offset_ >= img_->size()) + { + memcpy(buf, img_->data() + offset_, img_->size() - offset_); + *size = img_->size() - offset_; + offset_ = img_->size(); + } + else + { + memcpy(buf, img_->data() + offset_, *size); + offset_ += *size; + } + } + + return 0; +} + diff --git a/device/gxx-linux/usb/src/async_model/io/sent_img.h b/device/gxx-linux/usb/src/async_model/io/sent_img.h new file mode 100644 index 0000000..c59856b --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/io/sent_img.h @@ -0,0 +1,34 @@ +// readonly options +// +// 2023-04-26 + +#pragma once + +#include "data.h" +#include "imemory.h" + +class image_packet : public data_source +{ + MemoryPtr img_; + dyn_mem_ptr head_; + uint32_t offset_; + uint32_t sn_; + std::string info_; + bool info_over_; + +public: + image_packet(LPPACKIMAGE head, MemoryPtr img, uint32_t scanid, uint32_t sn, const void* info = nullptr, size_t info_size = 0); + +protected: + virtual ~image_packet(); + +public: + virtual bool is_memory_block(void) override; + virtual uint32_t get_rest(void) override; + + // following API valid when is_memory_block() return true + virtual uint8_t* ptr(void) override; + + // following API valid when is_memory_block() return false. return error code + virtual int fetch_data(void* buf, uint32_t* size) override; +}; diff --git a/device/gxx-linux/usb/src/common/usb_io.cpp b/device/gxx-linux/usb/src/async_model/io/usb_io.cpp similarity index 98% rename from device/gxx-linux/usb/src/common/usb_io.cpp rename to device/gxx-linux/usb/src/async_model/io/usb_io.cpp index 953bb11..6c12d28 100644 --- a/device/gxx-linux/usb/src/common/usb_io.cpp +++ b/device/gxx-linux/usb/src/async_model/io/usb_io.cpp @@ -5,9 +5,9 @@ #include #include #include "../../inc/logs_out.h" -#include "sys_util.h" -#include "log_util.h" -#include "encrypt.h" +#include "common/sys_util.h" +#include "common/log_util.h" +#include "common/encrypt.h" // #define TEST @@ -704,6 +704,7 @@ void async_usb_gadget::thread_pump_task(void) { packet_data_base_ptr pack_data = nullptr; data_source_ptr ds = nullptr; + bool notify_reply_ok = false; if(dh == nullptr) { @@ -716,6 +717,8 @@ void async_usb_gadget::thread_pump_task(void) status_.task_pack_id = pack->pack_id; used = data->get_rest(); reply = handle_bulk_command(data, &used, &pack_data); + notify_reply_ok = used & (INT32_MAX + 1); + used &= INT32_MAX; if(pack_data) { dh = dynamic_cast(pack_data); @@ -788,6 +791,8 @@ void async_usb_gadget::thread_pump_task(void) } write_bulk(dynamic_cast(reply)); + if(notify_reply_ok) + handle_bulk_command(data, nullptr, nullptr); reply->release(); reply = nullptr; } diff --git a/device/gxx-linux/usb/src/common/usb_io.h b/device/gxx-linux/usb/src/async_model/io/usb_io.h similarity index 97% rename from device/gxx-linux/usb/src/common/usb_io.h rename to device/gxx-linux/usb/src/async_model/io/usb_io.h index 4f30379..a996e54 100644 --- a/device/gxx-linux/usb/src/common/usb_io.h +++ b/device/gxx-linux/usb/src/async_model/io/usb_io.h @@ -4,16 +4,16 @@ // // created on 2023-03-10 -#include "referer.h" -#include "packet.h" -#include "ipc_util.h" +#include "common/referer.h" +#include "common/packet.h" +#include "common/ipc_util.h" #include "data.h" #include #include #include #include -#include "../../inc/usb_gadget.h" +#include "inc/usb_gadget.h" // callback proto diff --git a/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp new file mode 100644 index 0000000..d075ae2 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp @@ -0,0 +1,841 @@ +#include "async_scanner.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/log_util.h" +#include "common/sys_util.h" +#include "common/json/gb_json.h" +#include "common/sane_cfg.h" +#include "hardware/hardware.h" +#include "img_process/img_process.h" +#include "io/usb_io.h" +#include "io/sent_img.h" +#include "readonly_opts.h" + + +#ifdef TEMPORARY_API +extern int32_t (*scan_start)(void); +extern int32_t (*scan_stop)(void); +extern int32_t (*set_dpi)(int*, int*); +extern int32_t (*set_scan_num)(int); +extern int32_t (*set_image_receiver)(void(*rcv)(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, void* param), void* param); + +static bool reg_img_cb = true; +static void push_image(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, void* param) +{ + ((async_scanner*)param)->push_image(data_type, data, w, h, dpi_x, dpi_y, paper_ind, side, clr, status, img_new, img_over); +} +#endif + + + +static void dump_buf(uint8_t *data, int len) +{ + uint32_t addr = 0; + std::string cont(""), asc(""); + char buf[20] = { 0 }; + for(int i = 0; i < len; ++i) + { + if((i % 16) == 0) + { + if (cont.length()) + log_cls::log(LOG_LEVEL_ALL, "%s %s\n", cont.c_str(), asc.c_str()); + sprintf(buf, "0x%08x ", addr); + addr += 16; + cont = buf; + asc = ""; + } + else if((i % 8) == 0) + { + cont += " "; + } + + uint8_t v = data[i]; + sprintf(buf, "%02X ", v); + cont += buf; + if(v >= 0x20 && v < 0x7f) + asc.append(1, v); + else + asc += "."; + } + if(asc.length()) + { + std::string pad(" "); + if(asc.length() <= 8) + pad.erase((16 - asc.length()) * 3 + 2); + else if(asc.length() < 16) + pad.erase((16 - asc.length()) * 3); + else + pad = ""; + log_cls::log(LOG_LEVEL_ALL, "%s%s %s\n", cont.c_str(), pad.c_str(), asc.c_str()); + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +async_scanner::async_scanner(usb_gadget* gadget) : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0) +{ + log_cls::initialize(nullptr); + init(); + + auto bulk_handle = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* required) -> dyn_mem_ptr + { + LPPACK_BASE pack = (LPPACK_BASE)data->ptr(); + + if(used) + *used = data->get_rest(); + + return handle_bulk_cmd(pack, used, required); + }; + auto ctrl_unhandle = [&](struct usb_functionfs_event* pev) -> dyn_mem_ptr + { + return unhandled_ep0(pev); + }; + auto on_connect = [&](bool connected) -> void + { + log_cls::log(LOG_LEVEL_ALL, "USB %s\n", connected ? "connected" : "dis-connected"); + }; + usb_ = new async_usb_gadget(gadget, ctrl_unhandle, bulk_handle, on_connect); +} + +async_scanner::~async_scanner() +{ + if(usb_) + { + usb_->stop(); + usb_->release(); + } + if(cfg_mgr_) + cfg_mgr_->release(); +} + +void async_scanner::push_image(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over) +{ + if(data_type == IMG_CB_STOPPED) + { + if(w == 0) + w = scan_err_; + img_prc_->push_image((img_one_paper*)w, true); + } + else if(data_type == IMG_CB_STATUS) + { + if(scan_id_ == 0) + { + dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE)); + BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_STATUS_ROGER, 0, w); + reply->set_len(sizeof(PACK_BASE)); + usb_->write_bulk(reply); + reply->release(); + } + else + { + scan_err_ = w; + } + } + else if(data) + { + img_one_paper *paper = new img_one_paper(); + + paper->init_from(data, w, h, dpi_x, dpi_y, paper_ind, side, clr, status, img_new, img_over); + img_prc_->push_image(paper); + paper->release(); + + // paper count ... + dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE)); + BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_SCAN_PAPER_ROGER, scan_id_, paper_ind); + reply->set_len(sizeof(PACK_BASE)); + usb_->write_bulk(reply); + reply->release(); + } +} + + +dyn_mem_ptr async_scanner::unhandled_ep0(struct usb_functionfs_event* pev) +{ + return nullptr; +} +dyn_mem_ptr async_scanner::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ + dyn_mem_ptr reply = nullptr; + LPPACK_BASE pk = nullptr; + size_t base_head_size = sizeof(PACK_BASE); + + if(pack->size != base_head_size) + { + if(used) + { + log_cls::log(LOG_LEVEL_ALL, "Unknown Packet with %d bytes:\n", *used); + dump_buf((uint8_t*)pack, *used); + } + reply = dyn_mem::memory(base_head_size); + LPPACK_BASE p = (LPPACK_BASE)reply->ptr(); + BASE_PACKET_REPLY(*p, PACK_CMD_INVALID, pack->pack_id, pack->cmd); + reply->set_len(base_head_size); + + return reply; + } + + switch(pack->cmd) + { + case PACK_CMD_SYNC: + reply = handle_simple_roger(pack, used, required); + break; + case PACK_CMD_SETTING_GET_CUR: + reply = handle_get_opt_value(pack, used, required); + break; + case PACK_CMD_SETTING_GET: + reply = handle_get_opt_all(pack, used, required); + break; + case PACK_CMD_SETTING_SET: + reply = handle_set_opt(pack, used, required); + break; + case PACK_CMD_FILE_WRITE_REQ: + reply = handle_file_receive(pack, used, required); + break; + case PACK_CMD_FILE_READ_REQ: + reply = handle_file_send(pack, used, required); + break; + case PACK_CMD_SCAN_START: + reply = handle_scan_start(pack, used, required); + break; + case PACK_CMD_SCAN_STOP: + reply = handle_scan_stop(pack, used, required); + break; + default: + log_cls::log(LOG_LEVEL_ALL, "Unhandled Packet with command %d:\n", pack->cmd); + if(used) + { + dump_buf((uint8_t*)pack, *used); + } + reply = dyn_mem::memory(base_head_size); + LPPACK_BASE p = (LPPACK_BASE)reply->ptr(); + BASE_PACKET_REPLY(*p, pack->cmd + 1, pack->pack_id, EINVAL); + reply->set_len(base_head_size); + break; + } + + return reply; +} +void async_scanner::init(void) +{ + readonly_cfg* r = new readonly_cfg(); + cfg_mgr_ = new sane_cfg_mgr(); + cfg_mgr_->reg_sane_provider(dynamic_cast(r)); + r->release(); + + auto send_img = [&](LPPACKIMAGE head, MemoryPtr img, const void* info, size_t info_size) -> void + { + image_packet* imgp = nullptr; + uint32_t ind = 0; + + if(head) + { + { + LOCKER lock(locker_); + + ind = ++img_cnt_; + } + + imgp = new image_packet(head, img, scan_id_, ind, info, info_size); + usb_->write_bulk(imgp); + imgp->release(); + } + else + { + int wait = 0; + dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE)); + BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_SCAN_FINISHED_ROGER, scan_id_, info_size); + reply->set_len(sizeof(PACK_BASE)); + scan_id_ = 0; + while(!reply_start_ && wait++ < 200) + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + usb_->write_bulk(reply); + reply->release(); + } + }; + auto get_opt = [&](const char* name, void* buf, size_t* len) -> int32_t + { + std::string val(""); + int32_t ret = cfg_mgr_->get_config(val, name); + + if(ret == 0) + { + if(*len < val.length()) + { + ret = ENOMEM; + } + else + { + memcpy(buf, val.c_str(), val.length()); + } + *len = val.length(); + } + + return ret; + }; + img_prc_ = new img_processor(send_img, get_opt); + cfg_mgr_->reg_sane_provider(dynamic_cast(img_prc_)); + + auto on_image_captured = [&](int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over) -> void + { + push_image(data_type, data, w, h, dpi_x, dpi_y, paper_ind, side, clr, status, img_new, img_over); + }; + capture_ = new image_capture(on_image_captured); + cfg_mgr_->reg_sane_provider(dynamic_cast(capture_)); +} + +dyn_mem_ptr async_scanner::handle_simple_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ + uint32_t base_head_size = sizeof(PACK_BASE); + dyn_mem_ptr reply = dyn_mem::memory(base_head_size); + LPPACK_BASE pk = (LPPACK_BASE)reply->ptr(); + + *used = base_head_size; + BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, 0); + reply->set_len(base_head_size); + + return reply; +} +dyn_mem_ptr async_scanner::handle_get_opt_value(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ + uint32_t base_head_size = sizeof(PACK_BASE); + dyn_mem_ptr reply = nullptr; + LPPACK_BASE pk = nullptr; + + if(*used < base_head_size + pack->payload_len) + { + *used = 0; + } + else + { + std::string val(""), str(""); + uint32_t err = cfg_mgr_->get_config(val, pack->payload, &str); + LPCFGVAL cfg = nullptr; + + log_cls::log(LOG_LEVEL_ALL, "Option '%s' value: %s\n", pack->payload, str.c_str()); + reply = dyn_mem::memory(base_head_size + sizeof(CFGVAL) + strlen(pack->payload) + 1 + val.length() + 1); + pk = (LPPACK_BASE)reply->ptr(); + BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, err); + cfg = (LPCFGVAL)pk->payload; + cfg->val_size = val.length(); + cfg->val_off = 0; + cfg->name_off = val.length() + 1; + pk->payload_len = sizeof(CFGVAL) + strlen(pack->payload) + 1 + val.length() + 1; + 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; + } + + return reply; +} +dyn_mem_ptr async_scanner::handle_get_opt_all(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ + uint32_t base_head_size = sizeof(PACK_BASE); + dyn_mem_ptr reply = nullptr; + LPPACK_BASE pk = nullptr; + + *used = base_head_size; + { + std::string val(""); + uint32_t err = cfg_mgr_->get_config(val); + + reply = dyn_mem::memory(base_head_size + val.length() + 1); + pk = (LPPACK_BASE)reply->ptr(); + BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, err); + strcpy(pk->payload, val.c_str()); + pk->payload_len = val.length() + 1; + reply->set_len(base_head_size + val.length() + 1); + } + + return reply; +} +dyn_mem_ptr async_scanner::handle_set_opt(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ uint32_t base_head_size = sizeof(PACK_BASE); + dyn_mem_ptr reply = nullptr; + LPPACK_BASE pk = nullptr; + + if (*used < base_head_size + pack->payload_len) + *used = 0; + else + { + LPCFGVAL cfg = (LPCFGVAL)pack->payload, + cfg_ret = nullptr; + std::string name(cfg->data + cfg->name_off), val0(sane_cfg_provider::to_readable_string(cfg->data + cfg->val_off, (data_type)cfg->type)), val1(""); + size_t l = base_head_size + sizeof(CFGVAL) + name.length() + 1 + cfg->max_size + 1, val_size = cfg->val_size; + int32_t err = 0; + uint32_t after = 0; + + reply = dyn_mem::memory(l); + pk = (LPPACK_BASE)reply->ptr(); + cfg_ret = (LPCFGVAL)pk->payload; + cfg_ret->name_off = 0; + strcpy(cfg_ret->data + cfg_ret->name_off, name.c_str()); + cfg_ret->val_off = name.length() + 1; + memcpy(cfg_ret->data + cfg_ret->val_off, cfg->data + cfg->val_off, cfg->val_size); + cfg_ret->val_size = cfg->val_size; + cfg_ret->max_size = cfg->max_size; + cfg_ret->type = cfg->type; + err = cfg_mgr_->set_config(cfg->data + cfg->name_off, cfg_ret->data + cfg_ret->val_off, &val_size, &after); + cfg_ret->after_do = after; + cfg_ret->val_size = val_size; + BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, err); + pk->payload_len = sizeof(CFGVAL) + name.length() + 1 + cfg->max_size + 1; + reply->set_len(l); + val1 = sane_cfg_provider::to_readable_string(cfg_ret->data + cfg_ret->val_off, (data_type)cfg->type); + if(val0 == val1) + log_cls::log(LOG_LEVEL_DEBUG, "Set '%s' value to '%s'\n", name.c_str(), val0.c_str()); + else + log_cls::log(LOG_LEVEL_DEBUG, "Set '%s' value to '%s', but applied '%s'\n", name.c_str(), val0.c_str(), val1.c_str()); + } + + return reply; +} +dyn_mem_ptr async_scanner::handle_file_receive(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ + uint32_t base_head_size = sizeof(PACK_BASE); + dyn_mem_ptr reply = nullptr; + LPPACK_BASE pk = nullptr; + + if(*used < pack->payload_len + pack->size) + { + *used = 0; + } + else + { + LPTXFILE pfi = (LPTXFILE)pack->payload; + std::string path(pfi->path); + int err = 0; + file_saver *saver = new file_saver(); + + err = saver->open(path.c_str(), pfi->size); + reply = dyn_mem::memory(base_head_size); + reply->set_len(base_head_size); + BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err); + *used = base_head_size + pack->payload_len; + if(err) + { + saver->release(); + saver = nullptr; + } + else + { + saver->set_packet_param(pack->cmd, pack->pack_id); + } + log_cls::log(LOG_LEVEL_DEBUG, "receive file (%u bytes): %s = %d\n", pfi->size, path.c_str(), err); + *required = dynamic_cast(saver); + } + + return reply; +} +dyn_mem_ptr async_scanner::handle_file_send(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ + uint32_t base_head_size = sizeof(PACK_BASE); + dyn_mem_ptr reply = dyn_mem::memory(base_head_size); + LPPACK_BASE pk = (LPPACK_BASE)reply->ptr(); + + if(*used < pack->payload_len + pack->size) + { + *used = 0; + } + else + { + LPTXFILE pfi = (LPTXFILE)pack->payload; + std::string path(pfi->path); + int err = 0; + file_reader *reader = new file_reader(); + + err = reader->open(path.c_str()); + reply = dyn_mem::memory(base_head_size + sizeof(TXFILE)); + reply->set_len(base_head_size + sizeof(TXFILE)); + BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err); + *used = base_head_size + pack->payload_len; + log_cls::log(LOG_LEVEL_DEBUG, "To send file '%s' with %u bytes = %d\n", path.c_str(), reader->get_rest(), err); + if(err) + { + reader->release(); + reader = nullptr; + } + else + { + ((LPPACK_BASE)reply->ptr())->payload_len = sizeof(TXFILE); + ((LPTXFILE)((LPPACK_BASE)reply->ptr())->payload)->size = reader->get_rest(); + reader->set_packet_param(pack->cmd, pack->pack_id); + } + *required = dynamic_cast(reader); + } + + return reply; +} +dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ + if(!used) + { + reply_start_ = true; + return nullptr; + } + +#ifdef TEMPORARY_API + if(reg_img_cb) + { + reg_img_cb = set_image_receiver(::push_image, this); + } +#endif + + uint32_t base_head_size = sizeof(PACK_BASE); + dyn_mem_ptr reply = dyn_mem::memory(base_head_size); + + img_cnt_ = 0; + scan_id_ = pack->pack_id; + scan_err_ = 0; + reply_start_ = false; + + // { + // reg_image_callback(); + // ctrl_handler(-1, (usb_ctrlrequest*)SR_IM_CLEAR, (unsigned char*)0); + // log_cls::log(LOG_LEVEL_ALL, "Memory usage before starting to scan: %s\n", sys_util::format_readable_bytes(sys_util::get_memory_usage("scan")).c_str()); + // bool ret = ctrl_handler(-1, (usb_ctrlrequest*)15, (unsigned char*)0x160); // hardware configuration + // + // ctrl_handler(-1, (usb_ctrlrequest*)SR_SCAN_CNT, (unsigned char*)scan_cnt_); + // ctrl_handler(-1, (usb_ctrlrequest*)SR_SCAN_DPI, (unsigned char*)dpi_); + // ctrl_handler(-1, (usb_ctrlrequest*)SR_CONFIF_IMGPROCPARAM, (unsigned char*)0); + // log_cls::log(LOG_LEVEL_ALL, "Start scanning %d papers and %d DPI ...\n", scan_cnt_, dpi_); + // ret = ctrl_handler(-1, nullptr, nullptr); + // log_cls::log(LOG_LEVEL_ALL, "Start scanning %s\n", ret ? "OK" : "Failed"); + // log_cls::log(LOG_LEVEL_ALL, "Memory usage after scanning started: %s\n", sys_util::format_readable_bytes(sys_util::get_memory_usage("scan")).c_str()); + // } + + *used = base_head_size; + reply->set_len(base_head_size); + log_cls::log_memory_usage("before starting to scan"); + scan_err_ = capture_->start(); + log_cls::log_memory_usage("after scanning"); + BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, scan_err_); + *used |= INT32_MAX + 1; + + return reply; +} +dyn_mem_ptr async_scanner::handle_scan_stop(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ + uint32_t base_head_size = sizeof(PACK_BASE); + dyn_mem_ptr reply = dyn_mem::memory(base_head_size); + + log_cls::log(LOG_LEVEL_ALL, "Received command Stop-Scan.\n"); + BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, capture_->stop()); + reply->set_len(base_head_size); + *used = base_head_size; + + return reply; +} +dyn_mem_ptr async_scanner::handle_process_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +{ + uint32_t base_head_size = sizeof(PACK_BASE); + dyn_mem_ptr reply = dyn_mem::memory(base_head_size); + LPPACK_BASE pk = (LPPACK_BASE)reply->ptr(); + + *used = base_head_size + pack->payload_len; + BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, EINVAL); + reply->set_len(base_head_size); + + return reply; +} + + +uint32_t async_scanner::stop(void) +{ + if(usb_) + { + usb_->stop(); + } +} + +// void async_scanner::save_image(MemoryPtr data, bool img) +// { +// static uint64_t max_mem = 0; + +// if(img) +// { +// uint64_t n = sys_util::get_memory_usage("scan"); +// uint32_t que = 0; +// image_packet *ip = new image_packet(data, ++img_cnt_, scan_id_, n); + +// if(max_mem < n) +// max_mem = n; + +// que = usb_->write_bulk(ip); +// ip->release(); + +// // check has completed ? +// if(scan_over_pack_) +// { +// ctrl_handler(-2, (usb_ctrlrequest*)SR_GET_IMAGEPROCESSDONE, (unsigned char*)&n); +// if(n) +// { +// usb_->write_bulk(scan_over_pack_); +// scan_over_pack_->release(); +// scan_over_pack_ = nullptr; +// } +// } +// } +// else if(data) +// { +// HGIntInfo* info = (HGIntInfo*)data->data(); +// dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE)); +// int cmd = /*PACK_CMD_SCAN_FINISHED_ROGER*/0, +// err = 0; + +// if(info->From != HGType::MBEvent || scan_id_ == 0) +// log_cls::log(LOG_LEVEL_ALL, "Scanner event: From = %d, Code = %d, Img_Index = %d\n", info->From, info->Code, info->Img_Index); + +// if(info->From == HGType::MtBoard) +// { +// cmd = PACK_CMD_SCAN_FINISHED_ROGER; +// switch(info->Code) +// { +// case 2: +// err = SCANNER_STATUS_NO_PAPER; +// break; +// case 4: +// err = SCANNER_STATUS_COVER_OPENNED; +// break; +// case 8: +// err = SCANNER_STATUS_FEED_FAILED; +// break; +// case 0x10: +// err = SCANNER_STATUS_PAPER_JAMMED; +// break; +// case 0x20: +// err = SCANNER_STATUS_DOUBLE_FEEDED; +// break; +// case 0x40: +// err = SCANNER_STATUS_STAPLE_ON; +// break; +// case 0x80: +// err = SCANNER_STATUS_PAPER_ASKEW; +// break; +// case 0x20000: +// break; +// } +// } +// else if(info->From == HGType::IMG) +// { +// if(info->Code == 1) +// { +// err = SCANNER_STATUS_DOGEAR; +// cmd = PACK_CMD_SCAN_FINISHED_ROGER; +// } +// else if(info->Code == 2) +// { +// err = SCANNER_STATUS_SIZE_ERR; +// cmd = PACK_CMD_SCAN_FINISHED_ROGER; +// } +// } +// else if(info->From == HGType::V4L2 || info->From == HGType::STOPSCAN) +// { +// cmd = PACK_CMD_SCAN_FINISHED_ROGER; +// } + +// if(scan_id_ == 0 && info->From == HGType::MBEvent) +// { +// BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_STATUS_ROGER, 0, info->Code); +// reply->set_len(sizeof(PACK_BASE)); +// usb_->write_bulk(reply); +// } +// else +// { +// if(err && scan_err_ == 0) +// scan_err_ = err; +// if(scan_id_ && /*cmd == PACK_CMD_SCAN_FINISHED_ROGER*/info->From == HGType::STOPSCAN && scan_over_pack_ == nullptr) +// { +// char ebuf[20] = {0}; + +// err = scan_err_; +// log_cls::log(LOG_LEVEL_ALL, "Scan over with error: %s; Max memory usage: %s\n", log_cls::str_scanner_status((scanner_status)scan_err_, ebuf), sys_util::format_readable_bytes(max_mem).c_str()); +// max_mem = 0; +// BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), cmd, scan_id_, err); +// reply->set_len(sizeof(PACK_BASE)); +// scan_id_ = 0; + +// // check if the image-proc-queue has completed ... +// // ctrl_handler(-2, (usb_ctrlrequest*)SR_GET_IMAGEPROCESSDONE, (unsigned char*)&err); +// err = 1; +// if(err) +// usb_->write_bulk(reply); +// else +// { +// scan_over_pack_ = reply; +// scan_over_pack_->add_ref(); +// } +// } +// } +// 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 async_scanner::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +// { +// int32_t ret = EINVAL; + +// if(!len) +// return ret; + +// if(cfg_name) +// { +// gb_json *jsn = new gb_json(); +// if(jsn->attach_text(&cfg_text_[0])) +// { +// ret = inner_get_config(jsn, buf, len, cfg_name, strval); +// // gb_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(); + +// // if(*len < val.length()) +// // { +// // *len = val.length(); +// // ret = ENOMEM; +// // } +// // else +// // { +// // memcpy(buf, val.c_str(), val.length()); +// // *len = val.length(); +// // } +// // } +// jsn->release(); +// } +// } +// else +// { +// if(*len < cfg_text_.length() + 1) +// { +// *len = cfg_text_.length() + 4; +// ret = ENOMEM; +// } +// else +// { +// strcpy((char*)buf, cfg_text_.c_str()); +// *len = cfg_text_.length(); +// ret = 0; +// } +// } + +// return ret; +// } +// int32_t async_scanner::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +// { +// gb_json *jsn = new gb_json(); +// int32_t ret = EINVAL; + +// if(jsn->attach_text(&cfg_text_[0])) +// { +// gb_json* child = nullptr; + +// ret = ENOENT; +// if(jsn->get_value(cfg_name, child) && child) +// { +// int val = 0; +// child->get_value("affect", val); +// if(afterdo) +// *afterdo = val; + +// if(strcmp(cfg_name, "resolution") == 0) +// { +// child->get_value("cur", val); +// ret = EUCLEAN; +// val = *(int*)data; +// if(val == 100 || val == 150 || val == 200 || val == 300 || val == 600) +// ret = 0; +// else if(val < 125) +// val = 100; +// else if(val < 175) +// val = 150; +// else if(val < 250) +// val = 200; +// else if(val < 450) +// val = 300; +// else +// val = 600; +// *(int*)data = val; +// child->set_value("cur", val); +// dpi_ = val; +// log_cls::log(LOG_LEVEL_ALL, "Set %s to %d\n", cfg_name, dpi_); +// cfg_text_ = jsn->to_string(); +// } +// else if(strcmp(cfg_name, "count") == 0) +// { +// child->get_value("cur", val); +// ret = EUCLEAN; +// val = *(int*)data; +// if(val == -1 || val == 1) +// ret = 0; +// else +// val = -1; +// *(int*)data = val; +// child->set_value("cur", val); +// scan_cnt_ = val; +// log_cls::log(LOG_LEVEL_ALL, "Set %s to %d\n", cfg_name, scan_cnt_); +// cfg_text_ = jsn->to_string(); +// } +// child->release(); +// } +// jsn->release(); +// } + +// return ret; +// } +// void async_scanner::update_enabled(std::function get_opt) +// { +// gb_json *jsn = new gb_json(); +// int32_t ret = EINVAL; + +// if(jsn->attach_text(&cfg_text_[0])) +// { +// sane_cfg_provider::update_option_enable_status(jsn, get_opt); +// cfg_text_ = std::move(jsn->to_string()); +// } + +// jsn->release(); +// } +// int32_t async_scanner::get_value(const char* name, const char* key, std::string& val) +// { +// gb_json* root = new gb_json(), *child = nullptr; +// int32_t ret = ENOENT; + +// if(root->attach_text(&cfg_text_[0])) +// { +// if(root->get_value(name, child) && child) +// { +// if(sane_cfg_provider::raw_value_in_json(child, key, val)) +// ret = 0; +// child->release(); +// } +// } +// root->release(); + +// return ret; +// } + diff --git a/device/gxx-linux/usb/src/async_model/scanner/async_scanner.h b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.h new file mode 100644 index 0000000..b11bd41 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.h @@ -0,0 +1,65 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include "camtp.h" +#include "buildconf.h" +#include "usb_gadget.h" +#include "io/data.h" + +#include "common/referer.h" + +class async_usb_gadget; +class sane_cfg_mgr; +class image_capture; +class img_processor; +class gb_json; + +class async_scanner : public refer +{ + async_usb_gadget *usb_; + sane_cfg_mgr *cfg_mgr_; + image_capture *capture_; + img_processor *img_prc_; + + MUTEX locker_; + uint32_t img_cnt_; + uint32_t scan_id_; + uint32_t scan_err_; + volatile bool reply_start_; + + dyn_mem_ptr unhandled_ep0(struct usb_functionfs_event* pev); + dyn_mem_ptr handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + void init(void); + + dyn_mem_ptr handle_simple_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_get_opt_value(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_get_opt_all(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_set_opt(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_file_receive(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_file_send(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_scan_stop(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_process_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + +public: + async_scanner(usb_gadget* gadget); + +protected: + ~async_scanner(); + +public: + // void save_image(MemoryPtr data, bool img); + + // 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; + // virtual void update_enabled(std::function get_opt) override; + // virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + void push_image(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over); + +public: + uint32_t stop(void); +}; diff --git a/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.cpp b/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.cpp new file mode 100644 index 0000000..b95ebca --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.cpp @@ -0,0 +1,115 @@ +#include "readonly_opts.h" + +#include "common/json/gb_json.h" +#include "common/sys_util.h" + +#include + +static std::string readonly_json = + "{\"dev-sn\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"\\u8BBE\\u5907\\u5C5E\\u6027\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8bbe\\u5907\\u5e8f\\u5217\\u53f7\",\"desc\":\"\\u8bbe\\u5907\\u552f\\u4e00\\u7f16\\u7801\",\"type\":\"string\",\"cur\":\"G100S20230001\",\"size\":20,\"ver\":1},\"fmw-ver\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"\\u8BBE\\u5907\\u5C5E\\u6027\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u56fa\\u4ef6\\u7248\\u672c\\u53f7\",\"desc\":\"\\u8bbe\\u5907\\u9a71\\u52a8\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"cur\":\"FMWV1001\",\"size\":10,\"ver\":1},\"ip-addr\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"\\u8BBE\\u5907\\u5C5E\\u6027\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8bbe\\u5907IP\\u5730\\u5740\",\"desc\":\"\\u5f53\\u8bbe\\u5907\\u8fde\\u63a5\\u7f51\\u7edc\\u65f6\\u5206\\u914d\\u7684IP\\u5730\\u5740\",\"type\":\"string\",\"cur\":\"0.0.0.0\",\"size\":60,\"ver\":1},\"mac-addr\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"\\u8BBE\\u5907\\u5C5E\\u6027\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8bbe\\u5907MAC\\u5730\\u5740\",\"desc\":\"\\u8bbe\\u5907MAC\\u5730\\u5740\",\"type\":\"string\",\"cur\":\"00:11:22:33:44:55\",\"size\":30,\"ver\":1}}"; + +// C2-B0-AF-79-75-D6 +// + +readonly_cfg::readonly_cfg() : jsn_(nullptr) +{ + jsn_ = new gb_json(); + jsn_->attach_text(&readonly_json[0]); +} +readonly_cfg::~readonly_cfg() +{ + jsn_->release(); +} + +int32_t readonly_cfg::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + if (!len) + return EINVAL; + + std::string val(""), str(""); + + if (cfg_name) + { + if (strcmp(cfg_name, "ip-addr") == 0) + str = val = sys_util::get_ip(); + else if (strcmp(cfg_name, "mac-addr") == 0) + str = val = sys_util::get_mac(); + else + { + gb_json* child = nullptr; + if (jsn_->get_value(cfg_name, child) && child) + { + val = sane_cfg_provider::sane_option_value_get(child, "cur", &str); + + child->release(); + } + } + } + else + { + std::string cur(sys_util::get_ip()); + if (!cur.empty()) + { + gb_json* child = nullptr; + if (jsn_->get_value("ip-addr", child) && child) + { + child->set_value("cur", cur.c_str()); + child->release(); + } + } + + cur = sys_util::get_mac(); + if (!cur.empty()) + { + gb_json* child = nullptr; + if (jsn_->get_value("mac-addr", child) && child) + { + child->set_value("cur", cur.c_str()); + child->release(); + } + } + + val = jsn_->to_string(); + } + + if (val.empty()) + return ENOENT; + + if(strval) + *strval = std::move(str); + + if (*len < val.length()) + { + *len = val.length() + 4; + return ENOMEM; + } + else + { + memcpy(buf, val.c_str(), val.length()); + *len = val.length(); + + return 0; + } +} +int32_t readonly_cfg::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + // read-only attributes not support this operation !!! + return EINVAL; +} +void readonly_cfg::update_enabled(std::function get_opt) +{} +int32_t readonly_cfg::get_value(const char* name, const char* key, std::string& val) +{ + int32_t ret = ENOENT; + gb_json* child = nullptr; + + if(jsn_->get_value(name, child) && child) + { + if(sane_cfg_provider::raw_value_in_json(child, key, val)) + ret = 0; + + child->release(); + } + + return ret; +} diff --git a/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.h b/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.h new file mode 100644 index 0000000..a32a5c6 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.h @@ -0,0 +1,31 @@ +// readonly options +// +// 2023-04-26 + +#pragma once + +#include "common/sane_cfg.h" + +class gb_json; + +// C2-B0-AF-79-75-D6 + +class readonly_cfg : public sane_cfg_provider +{ + gb_json* jsn_; + + std::string get_ip(void); + std::string get_mac(void); + +public: + readonly_cfg(); + +protected: + ~readonly_cfg(); + +public: + virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) override; + virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_value(const char* name, const char* key, std::string& val) override; +}; diff --git a/device/gxx-linux/usb/src/common/CMakeLists.txt b/device/gxx-linux/usb/src/common/CMakeLists.txt deleted file mode 100644 index 466b700..0000000 --- a/device/gxx-linux/usb/src/common/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -project(common) -add_compile_options(-std=c++11) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") -aux_source_directory(${PROJECT_SOURCE_DIR} DIR_SRCS) -file(GLOB DIR_HEADS "${PROJECT_SOURCE_DIR}/*" "${PROJECT_SOURCE_DIR}/json/*") -set(DIR_SRCS ${DIR_SRCS} ${DIR_HEADS}) -add_library(${PROJECT_NAME} STATIC ${DIR_SRCS}) - -target_link_libraries(${PROJECT_NAME} PRIVATE - dl - pthread - rt - ) -target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR} - ) -set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../scanner/build/) diff --git a/device/gxx-linux/usb/src/common/cmd.cpp b/device/gxx-linux/usb/src/common/cmd.cpp deleted file mode 100644 index d8abf93..0000000 --- a/device/gxx-linux/usb/src/common/cmd.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "cmd.h" - - - - -namespace parser -{ - static void command_line_to_arguments(const char* cmdl, std::vector& args) - { - while(*cmdl) - { - const char* h = cmdl; - while(*h == ' ' || *h == '\t') - h++; - if(*h == 0) - break; - - cmdl = h; - if(*h == '\"') - { - cmdl++; - h++; - while(*h) - { - if(*h == '\"') - break; - if(*h == '\\') - h++; - h++; - } - } - else - { - while(*h) - { - if(*h == ' ' || *h == '\t') - break; - h++; - } - } - if(h > cmdl) - args.push_back(std::string(cmdl, h - cmdl)); - else if(*h == '\"') - args.push_back(""); - - if(*h == 0) - break; - - cmdl = h + 1; - } - } -} - - - - -cmd_line::cmd_line() -{} -cmd_line::~cmd_line() -{} - -cmd_line* cmd_line::from_console(const char* tips) -{ - std::string in(""); - char ch = 0; - - if(!tips || *tips == 0) - tips = "input"; - - printf("%s%s>%s", CONSOLE_COLOR_FRONT_BLUE, tips, CONSOLE_COLOR_NONE); - while((ch = getchar()) != '\n') - in.append(1, ch); - - return cmd_line::from_command_line(in.c_str()); -} -cmd_line* cmd_line::from_command_line(const char* cmdl) -{ - cmd_line* cmd = new cmd_line(); - - cmd->cmd_line_ = cmdl; - parser::command_line_to_arguments(cmdl, cmd->arguments_); - - return cmd; -} - -size_t cmd_line::count(void) -{ - return arguments_.size(); -} -const char* cmd_line::parameter(int ind) -{ - if(ind >= 0 && ind < arguments_.size()) - return arguments_[ind].c_str(); - else - return nullptr; -} -const char* cmd_line::parameter(const char* key) -{ - for(int i = 0; i < arguments_.size() - 1; ++i) - { - if(arguments_[i] == key) - return arguments_[i + 1].c_str(); - } - - return nullptr; -} diff --git a/device/gxx-linux/usb/src/common/cmd.h b/device/gxx-linux/usb/src/common/cmd.h deleted file mode 100644 index 91a65c3..0000000 --- a/device/gxx-linux/usb/src/common/cmd.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -// command line utility -// -// created on 2023-02-10 -// - -#include "referer.h" -#include -#include - -#define CONSOLE_COLOR_NONE "\033[0m" -#define CONSOLE_COLOR_FRONT_BLACK "\033[0;30m" -#define CONSOLE_COLOR_FRONT_DARK_GRAY "\033[1;30m" -#define CONSOLE_COLOR_FRONT_RED "\033[0;31m" -#define CONSOLE_COLOR_FRONT_LIGHT_RED "\033[1;31m" -#define CONSOLE_COLOR_FRONT_GREEN "\033[0;32m" -#define CONSOLE_COLOR_FRONT_LIGHT_GREEN "\033[1;32m" -#define CONSOLE_COLOR_FRONT_BROWN "\033[0;33m" -#define CONSOLE_COLOR_FRONT_YELLOW "\033[1;33m" -#define CONSOLE_COLOR_FRONT_BLUE "\033[0;34m" -#define CONSOLE_COLOR_FRONT_LIGHT_BLUE "\033[1;34m" -#define CONSOLE_COLOR_FRONT_PURPLE "\033[0;35m" -#define CONSOLE_COLOR_FRONT_LIGHT_PURPLE "\033[1;35m" -#define CONSOLE_COLOR_FRONT_CYAN "\033[0;36m" -#define CONSOLE_COLOR_FRONT_LIGHT_CYAN "\033[1;36m" -#define CONSOLE_COLOR_FRONT_LIGHT_GRAY "\033[0;37m" -#define CONSOLE_COLOR_FRONT_WHITE "\033[1;37m" - -#define CONSOLE_COLOR_BACK_BLACK "\033[0;40m" -#define CONSOLE_COLOR_BACK_DARK_GRAY "\033[1;40m" -#define CONSOLE_COLOR_BACK_RED "\033[0;41m" -#define CONSOLE_COLOR_BACK_LIGHT_RED "\033[1;41m" -#define CONSOLE_COLOR_BACK_GREEN "\033[0;42m" -#define CONSOLE_COLOR_BACK_LIGHT_GREEN "\033[1;42m" -#define CONSOLE_COLOR_BACK_BROWN "\033[0;43m" -#define CONSOLE_COLOR_BACK_YELLOW "\033[1;43m" -#define CONSOLE_COLOR_BACK_BLUE "\033[0;44m" -#define CONSOLE_COLOR_BACK_LIGHT_BLUE "\033[1;44m" -#define CONSOLE_COLOR_BACK_PURPLE "\033[0;45m" -#define CONSOLE_COLOR_BACK_LIGHT_PURPLE "\033[1;45m" -#define CONSOLE_COLOR_BACK_CYAN "\033[0;46m" -#define CONSOLE_COLOR_BACK_LIGHT_CYAN "\033[1;46m" -#define CONSOLE_COLOR_BACK_LIGHT_GRAY "\033[0;47m" -#define CONSOLE_COLOR_BACK_WHITE "\033[1;47m" - - -namespace console -{ - // special effects: - // \033[0m close all attributes - // \033[1m set high-light - // \033[4m underline - // \033[5m blink - // \033[7m reverse(反显) - // \033[8m blanking(消隐) - // \033[30m -- \033[37m set foreground color - // \033[40m -- \033[47m set background color - // - // cursor position: - // \033[nA move up n lines - // \033[nB move down n lines - // \033[nC move right n cols - // \033[nD move left n cols - // \033[y;xH set cursor position - // \033[2J clear screen - // \033[K clear the line after cursor position - // \033[s save cursor position - // \033[u restore cursor position - // \033[?25l hide cursor - // \033[?25h show cursor -}; - -class cmd_line : public refer -{ - std::string cmd_line_; - std::vector arguments_; - -protected: - cmd_line(); - ~cmd_line(); - -public: - static cmd_line* from_console(const char* tips); - static cmd_line* from_command_line(const char* cmdl); - -public: - size_t count(void); - const char* parameter(int ind); - const char* parameter(const char* key); -}; - diff --git a/device/gxx-linux/usb/src/common/event_monitor.cpp b/device/gxx-linux/usb/src/common/event_monitor.cpp deleted file mode 100644 index 657f3b1..0000000 --- a/device/gxx-linux/usb/src/common/event_monitor.cpp +++ /dev/null @@ -1,257 +0,0 @@ -#include "event_monitor.h" - -// #define __USE_GNU // for gettid of including file 'bits/unistd_ext.h' - -#include /* nonblocking */ -#include /*setrlimit */ -#include -#include -#include -#include -#include -#include -// #include // for gettid -#include -#include -#include - -#include "log_util.h" - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// event_handler -event_handler::event_handler() -{} -event_handler::~event_handler() -{} - - - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// parent_holder -parent_holder::parent_holder() -{} -parent_holder::~parent_holder() -{} - - - - - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// linux - epoll wrapper ... -class epoll_wrapper : public event_monitor -{ - int32_t epoll_fd_; - int32_t quit_fd_[2]; - volatile bool run_; - std::vector threads_; - - static int32_t epoll_max; - - void clear_threads(void) - { - if(threads_.size()) - { - for (size_t i = 0; i < threads_.size(); ++i) - { - if (threads_[i]->joinable()) - threads_[i]->join(); - threads_[i].reset(); - } - threads_.clear(); - } - } - void close_monitor_fd(void) - { - if (epoll_fd_ != -1) - close(epoll_fd_); - epoll_fd_ = -1; - } - void clear(void) - { - clear_threads(); - close_monitor_fd(); - } - void monitor_thread(void) - { - log_cls::log(LOG_LEVEL_DEBUG, "monitor thread(%p) of object(%p) is working ...\n", gettid(), this); - while (run_) - { - struct epoll_event evs; - - memset(&evs, 0, sizeof(evs)); - if (epoll_wait(epoll_fd_, &evs, 1, -1) == -1) - continue; - if (evs.events == EPOLLOUT && evs.data.fd == quit_fd_[1]) - break; - - if (evs.events == EPOLLIN) - ((event_handler*)evs.data.ptr)->on_event(event_handler::EVENT_READ, nullptr, 0); - else if (evs.events == EPOLLOUT) - ((event_handler*)evs.data.ptr)->on_event(event_handler::EVENT_WRITE, nullptr, 0); - else - ; - } - log_cls::log(LOG_LEVEL_DEBUG, "monitor thread(%p) of object(%p) finished working.\n", gettid(), this); - } - -protected: - virtual ~epoll_wrapper() - { - stop(); - } - -public: - epoll_wrapper(const char* desc) : event_monitor(desc), epoll_fd_(-1), run_(true) - { - memset(quit_fd_, -1, sizeof(quit_fd_)); - } - -public: - virtual int32_t start(int32_t threads = 1) override - { - int32_t ret = stop(); - struct rlimit rt; - - rt.rlim_max = rt.rlim_cur = epoll_wrapper::epoll_max; - if (ret == 0 && setrlimit(RLIMIT_NOFILE, &rt) == 0) - { - epoll_fd_ = epoll_create(epoll_wrapper::epoll_max); - if (epoll_fd_ == -1) - { - ret = errno; - log_cls::log(LOG_LEVEL_FATAL, "epoll_create for '%s' failed: %s\n", desc_.c_str(), strerror(ret)); - } - else - { - run_ = true; - for (size_t i = 0; i < (size_t)threads; ++i) - { - THREAD_PTR t;//(new std::thread(&epoll_wrapper::monitor_thread, this)); - t.reset(new std::thread(&epoll_wrapper::monitor_thread, this)); - threads_.push_back(t); - } - } - } - else - { - log_cls::log(LOG_LEVEL_FATAL, "setrlimit for '%s-epoll' failed: %s\n", desc_.c_str(), strerror(ret)); - } - - return ret; - } - virtual int32_t stop(void) override - { - if(threads_.size()) - { - struct epoll_event ev; - #ifdef __USE_GNU - pipe2(quit_fd_, O_NONBLOCK); - #else - pipe(quit_fd_); - #endif - - log_cls::log(LOG_LEVEL_DEBUG, "quit fd[0] = %p, fd[1] = %p\n", quit_fd_[0], quit_fd_[1]); - - run_ = false; - ev.data.fd = quit_fd_[1]; - ev.events = EPOLLOUT | EPOLLET | EPOLLONESHOT; - for(size_t i = 0; i < threads_.size(); ++i) - epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, ev.data.fd, &ev); - clear_threads(); - close(quit_fd_[0]); - close(quit_fd_[1]); - memset(quit_fd_, -1, sizeof(quit_fd_)); - } - - close_monitor_fd(); - - return 0; - } - - virtual int32_t add_fd(event_handler* handler) override - { - struct epoll_event ev; - int32_t ret = -1; - - if (!handler || handler->get_fd() == -1) - return EINVAL; - - if (epoll_fd_ == -1) - return EFAULT; - - handler->add_ref(); // add ref for epoll_event holder ... - ev.data.ptr = handler; - ev.events = EPOLLIN | EPOLLOUT | EPOLLET; // EPOLLONESHOT | EPOLLHUP - ret = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, handler->get_fd(), &ev); - if (ret == -1) - { - ret = errno; - log_cls::log(LOG_LEVEL_FATAL, "add fd(%d) to %s-epoll failed: %s\n", handler->get_fd(), desc_.c_str(), strerror(ret)); - handler->release(); - } - - return ret; - } - virtual int32_t remove_fd(event_handler* handler) override - { - struct epoll_event ev; - int32_t ret = -1; - - if (!handler || handler->get_fd() == -1) - return EINVAL; - - if (epoll_fd_ == -1) - return EFAULT; - - ev.data.ptr = handler; - ev.events = EPOLLIN | EPOLLOUT | EPOLLET | EPOLLHUP; // EPOLLONESHOT - ret = epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, handler->get_fd(), &ev); - - if (ret == 0) - { - // ENOENT returned if object 'handler' has not registered, so we can free it here when success in EPOLL_CTL_DEL ... - handler->release(); - } - else - { - ret = errno; - log_cls::log(LOG_LEVEL_FATAL, "remove fd(%d) from %s-epoll failed: %s\n", handler->get_fd(), desc_.c_str(), strerror(ret)); - } - - return ret; - } -}; -int32_t epoll_wrapper::epoll_max = 100; - - - - - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// event_handler -event_monitor::event_monitor(const char* desc) : desc_(desc ? desc : "") -{ - log_cls::log(LOG_LEVEL_DEBUG, "+event_monitor(%p) of '%s' contructing ...\n", this, desc_.c_str()); -} -event_monitor::~event_monitor() -{ - log_cls::log(LOG_LEVEL_DEBUG, "-event_monitor(%p) of '%s' destroyed\n", this, desc_.c_str()); -} - -event_monitor* event_monitor::create(const char* desc, int32_t type) -{ - if (type == EV_TYPE_EPOLL) - return dynamic_cast(new epoll_wrapper(desc)); - else - return nullptr; -} diff --git a/device/gxx-linux/usb/src/common/event_monitor.h b/device/gxx-linux/usb/src/common/event_monitor.h deleted file mode 100644 index 2a77a29..0000000 --- a/device/gxx-linux/usb/src/common/event_monitor.h +++ /dev/null @@ -1,153 +0,0 @@ -#pragma once - -// event monitor -// -// created on 2022-11-29 -// - -#include "referer.h" -#include "packet.h" - -#include -#include - -typedef std::shared_ptr THREAD_PTR; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// event definition ... -enum scanner_event -{ - SCANNER_EVENT_NONE = 0, - - // 1 - IPC - SCANNER_EVENT_IPC_DATA_RECEIVED = 1, - SCANNER_EVENT_IPC_DATA_SENT, - - // 2 - image-collector - SCANNER_EVENT_COLLECTOR_WORKING = 100, // on_event(, nullptr, 0), the first message after start success - - // normal image, double feeding image, jammed image, stapled imge, size-check error image ... - SCANNER_EVENT_COLLECTOR_IMG_DATA, // on_event(, (LPIMGD)data, bytes of data), image data transfer, buffer can be re-used when return - - SCANNER_EVENT_COLLECTOR_PAPER_ON, // on_event(, (bool*)paper_on, (bool)local_display) - SCANNER_EVENT_COLLECTOR_COVER_OPENNED, // on_event(, (bool*)openned, (bool)local_display) - SCANNER_EVENT_COLLECTOR_SLEEPPING, // on_event(, (bool*)sleepping, (bool)local_display) - SCANNER_EVENT_COLLECTOR_ERROR, // on_event(, (char*)err-msg, (bool)local_display), used when unknown fatal error occurs! - - SCANNER_EVENT_COLLECTOR_STOPPED, // on_event(, (char*)err-msg, (size_t)err-code), the last message after start success - - // 3 - image-process - SCANNER_EVENT_IMAGE_PROC_FINAL_BUF = 200, // on_event(, (void**)buf, (size_t)len), get buffer for store the final image - SCANNER_EVENT_IMAGE_PROC_OK, // on_event(, ) - SCANNER_EVENT_IMAGE_PROC_ERR, - - // 4 - resource - SCANNER_EVENT_RESOURCE_LOW_MEM = 300, // on_event(, (bool*)low_mem, (bool)local_display) - SCANNER_EVENT_RESOURCE_LOW_DISK, // on_event(, (bool*)low_disk, (bool)local_display) - SCANNER_EVENT_RESOURCE_HIGH_CPU, // on_event(, (bool*)high_cpu, (bool)local_display) -}; - -typedef struct _img_data -{ - LPPACKIMAGE info; - uint8_t* data; -}IMGD, *LPIMGD; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// object event_handler -// -// derived from 'event_handler' if your class will handle some events of drived by events -// -class event_handler : public refer -{ -protected: - event_handler(); - virtual ~event_handler(); - -public: - virtual int32_t on_event(int32_t ev, void* data, size_t data_len) = 0; - virtual int32_t get_fd(void) = 0; - - enum - { - EVENT_READ = 0, - EVENT_WRITE, - }; -}; - -class parent_holder : public refer -{ -protected: - parent_holder(); - virtual ~parent_holder(); - -public: - virtual int32_t stop(void) = 0; // stop work and release parent ptr -}; - -// event_monitor to manage an event-driven model, this will trigger EVENT_READ/EVENT_WRITE events to 'handler' -// -class event_monitor : public refer -{ -protected: - std::string desc_; - -protected: - event_monitor(const char* desc); - virtual ~event_monitor(); - -public: - virtual int32_t start(int32_t threads = 1) = 0; - virtual int32_t stop(void) = 0; - - virtual int32_t add_fd(event_handler* handler) = 0; - virtual int32_t remove_fd(event_handler* handler) = 0; - - enum - { - EV_TYPE_POLL = 1, - EV_TYPE_EPOLL, - }; - static event_monitor* create(const char* desc, int32_t type = EV_TYPE_EPOLL); -}; - -class sane_cfg_provider : public refer -{ -public: - sane_cfg_provider() - {} - virtual ~sane_cfg_provider() - {} - -public: - // Function: get all or given name configuration value - // - // Parameters: buf - to receive the configuration value or all configuration JSON - // - // len - [in] bytes of 'buf', [out] - content bytes in 'buf', or minimum size needed - // - // cfg_name - given configuration name, if set, put current value of the configuration in 'buf', - // or put all configurations JSON text in 'buf' if was nullptr. refer to SANE-config - // - // Return: 0 - on success - // EINVAL - if paramter 'len' was nullptr - // ENOMEM - if size of 'buf' was too small, the minimum size needed is stored in 'len' - // ENOENT - the configuration named 'cfg_name' has not found - virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr) = 0; - - // Function: set value of configuration named 'cfg_name' - // - // Parameters: cfg_name - the configuration name - // - // data - the value address, nullptr is for restore to default value - // (bool*), (int*), (double*), (char*) - // - // len - bytes in 'data' - // - // Return: 0 - on success - // EINVAL - parameter was invalid. 'cfg_name' was nullptr - // ENOENT - configuration 'cfg_name' was not found - // EUCLEAN - content in 'data' was not exact, the exact value is stored in 'data', and bytes in 'len' - virtual int32_t set_config(const char* cfg_name, void* data, size_t* len) = 0; -}; - diff --git a/device/gxx-linux/usb/src/common/ipc_wrapper.cpp b/device/gxx-linux/usb/src/common/ipc_wrapper.cpp deleted file mode 100644 index 5c9fdac..0000000 --- a/device/gxx-linux/usb/src/common/ipc_wrapper.cpp +++ /dev/null @@ -1,373 +0,0 @@ -#include "ipc_wrapper.h" - -#include -#include - -#include "log_util.h" -#include "ipc_util.h" -#include "sys_util.h" - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ipc_wrapper_shm -class ipc_wrapper_shm : public ipc_wrapper -{ - enum data_ind - { - DATA_INTER_CMD = 0, - }; - enum internal_cmd - { - INTER_CMD_NONE = 0, - INTER_CMD_EXIT, - }; - typedef struct _shm_pack - { - size_t space; // buffer length - size_t bytes; // data length - char data[4]; - }SHMPACK, *LPSHMPACK; - typedef struct _sync_shm // 1-lock(write_lock) --> 2-write content --> 3-notify read --> 4-wait(wait_sent) --> 5-return step 2 if data has not sent finished, or else to 6 --> 6-release(write_lock) --> 7-over - { - sem_t wait_arrive; // read event - sem_t wait_sent; // peer has read, i can re-write now - sem_t notify_read; // notify peer to read - sem_t notify_write; // notify peer to write - char data[8]; // internal data - }SYNCSHM, *LPSYNCSHM; - volatile bool run_; - MUTEX write_lock_; - int32_t id_; - shared_mem* shm_; - LPSYNCSHM sync_shm_; - linux_event* wait_arrive_; - linux_event* wait_sent_; - linux_event* notify_write_; - linux_event* notify_read_; - THREAD_PTR thread_; - LPSHMPACK buf_in_; - LPSHMPACK buf_out_; - bool buf_out_used_; - volatile bool cancel_write_; - - void create(const char* file, int32_t id, size_t bytes, unsigned sent_percent) - { - int32_t err = 0; - - shm_ = new shared_mem(); - err = shm_->open(id, &bytes, file); - if (err) - { - log_cls::log(LOG_LEVEL_FATAL, "ipc_wrapper_shm(%p) open shared memory(%s, %d, %s) failed: %s\n" - , this, file, id, sys_util::format_readable_bytes(bytes).c_str(), strerror(err)); - shm_->release(); - shm_ = nullptr; - - return; - } - - SHMPACK pack = { 0 }; - std::string desc("ipc_wrapper_shm-"); - char buf[80] = { 0 }, *ptr = shm_->get_mem(&pack.space); - int32_t pack_head = ALIGN_INT(sizeof(pack), 16), head = ALIGN_INT(sizeof(SYNCSHM), 16); - - sprintf(buf, "%d-", id); - desc += buf; - - sync_shm_ = (LPSYNCSHM)ptr; - ptr += head; - pack.space -= head + pack_head * 2; - head = ALIGN_INT(pack.space * sent_percent / 100, 16); - if (shm_->is_first()) - { - SYNCSHM ss; - - memcpy(sync_shm_, &ss, sizeof(ss)); - buf_in_ = (LPSHMPACK)ptr; - buf_in_->space = pack.space - head; - ptr += buf_in_->space + pack_head; - buf_out_ = (LPSHMPACK)ptr; - buf_out_->space = head; - //* - wait_arrive_ = new linux_event(&sync_shm_->wait_arrive, true, (desc + "wait_arrive").c_str()); - wait_sent_ = new linux_event(&sync_shm_->wait_sent, true, (desc + "wait_sent").c_str()); - notify_read_ = new linux_event(&sync_shm_->notify_read, true, (desc + "notify_read").c_str()); - notify_write_ = new linux_event(&sync_shm_->notify_write, true, (desc + "notify_write").c_str()); - /*/ - wait_arrive_ = new linux_event((desc + "wait_arrive").c_str(), ""); - wait_sent_ = new linux_event((desc + "wait_sent").c_str(), ""); - notify_write_ = new linux_event((desc + "notify_write").c_str(), ""); - notify_read_ = new linux_event((desc + "notify_read").c_str(), ""); - ///*//////////// - memset(sync_shm_->data, 0, sizeof(sync_shm_->data)); - } - else - { - //* - wait_sent_ = new linux_event(&sync_shm_->notify_write, false, (desc + "wait_sent").c_str()); - wait_arrive_ = new linux_event(&sync_shm_->notify_read, false, (desc + "wait_arrive").c_str()); - notify_write_ = new linux_event(&sync_shm_->wait_sent, false, (desc + "notify_write").c_str()); - notify_read_ = new linux_event(&sync_shm_->wait_arrive, false, (desc + "notify_read").c_str()); - /*/ - wait_arrive_ = new linux_event((desc + "notify_read").c_str(), ""); - wait_sent_ = new linux_event((desc + "notify_write").c_str(), ""); - notify_read_ = new linux_event((desc + "wait_arrive").c_str(), ""); - notify_write_ = new linux_event((desc + "wait_sent").c_str(), ""); - ///*//////////// - buf_out_ = (LPSHMPACK)ptr; - buf_in_ = (LPSHMPACK)(ptr + pack_head + buf_out_->space); - } - - thread_.reset(new std::thread(&ipc_wrapper_shm::read_thread, this)); - // handler_->on_event(event_handler::EVENT_WRITE, buf_out_->data, buf_size_); - } - void read_thread(void) - { - event_handler* handler = handler_; - - handler->add_ref(); - while (run_) - { - wait_arrive_->wait(); - if (!run_) - break; - if (!shm_->is_first() && sync_shm_->data[DATA_INTER_CMD] == INTER_CMD_EXIT) - break; - - handler->on_event(SCANNER_EVENT_IPC_DATA_RECEIVED, buf_in_->data, buf_in_->bytes); - notify_write_->trigger(); - } - handler->release(); - } - -public: - ipc_wrapper_shm(const char* file, int32_t id - , size_t bytes - , event_handler* handler - , unsigned sent_percent = 50) - : ipc_wrapper(handler), run_(true), shm_(nullptr), sync_shm_(nullptr) - , wait_arrive_(nullptr), wait_sent_(nullptr), notify_write_(nullptr), notify_read_(nullptr) - , buf_in_(nullptr), buf_out_(nullptr), id_(id), buf_out_used_(false), cancel_write_(false) - { - create(file, id, bytes, sent_percent); - } - -protected: - ~ipc_wrapper_shm() - {} - -public: - virtual int32_t write(const char* pack, size_t * bytes, bool kbuf, unsigned timeout = WAIT_INFINITE) override - { - if (!shm_) - return ENOTCONN; - - // invoke in read-thread is not allowed - if(std::this_thread::get_id() == thread_->get_id()) - return EDEADLOCK; - - LOCKER lock(write_lock_); - size_t rest = *bytes; - int32_t ret = 0; - - cancel_write_ = false; - if (kbuf) - { - buf_out_->bytes = rest; - notify_read_->trigger(); - if (wait_sent_->wait(timeout)) - rest = 0; - else - ret = ETIME; - } - else - { - chronograph timer; - while (rest) - { - buf_out_->bytes = rest > buf_out_->space ? buf_out_->space : rest; - memcpy(buf_out_->data, pack, buf_out_->bytes); - notify_read_->trigger(); - - pack += buf_out_->space; - if (!wait_sent_->wait(timeout)) - break; - if (cancel_write_) - break; - - if (rest <= buf_out_->space) - { - rest = 0; - break; - } - rest -= buf_out_->space; - - if (timeout) - { - uint64_t t = timer.elapse_ms(); - if (t >= timeout) - break; - - timeout -= t; - timer.reset(); - } - } - if (cancel_write_) - ret = ECANCELED; - else if (rest) - ret = ETIME; - } - *bytes -= rest; - - return ret; - } - virtual bool cancel_write(void) override - { - cancel_write_ = true; - if (wait_sent_->is_waiting()) - { - wait_sent_->trigger(); - wait_sent_->reset(); // sure ? - } - - return true; - } - virtual bool is_ok(void) override - { - return shm_ != nullptr; - } - virtual bool is_first(void) override - { - return shm_ && shm_->is_first(); - } - - virtual void* get_kbuf(size_t* bytes) override - { - if (!bytes) - return nullptr; - - if (buf_out_used_) - { - *bytes = 0; - - return nullptr; - } - - buf_out_used_ = true; - *bytes = buf_out_->space; - - return buf_out_->data; - } - virtual void release_kbuf(void* buf) override - { - buf_out_used_ = false; - } - virtual void clear_kernel_objects(void) override - { - std::string desc("ipc_wrapper_shm-"); - char id[20] = { 0 }; - - sprintf(id, "%d-", id_); - desc += id; - linux_event::clear_named_event((desc + "wait_arrive").c_str()); - linux_event::clear_named_event((desc + "wait_sent").c_str()); - linux_event::clear_named_event((desc + "notify_write").c_str()); - linux_event::clear_named_event((desc + "notify_read").c_str()); - - shm_->clear_kernel_object(); - } - virtual int32_t stop(void) override - { - run_ = false; - if (shm_) - { - wait_arrive_->trigger(); - if (thread_.get() && thread_->joinable()) - thread_->join(); - thread_.reset(); - - if (is_first()) - { - sync_shm_->data[DATA_INTER_CMD] = INTER_CMD_EXIT; - notify_read_->trigger(); - wait_sent_->wait(100); - } - notify_read_->release(); - notify_read_ = nullptr; - notify_write_->release(); - notify_write_ = nullptr; - wait_arrive_->release(); - wait_arrive_ = nullptr; - wait_sent_->release(); - wait_sent_ = nullptr; - sync_shm_ = nullptr; - buf_in_ = buf_out_ = nullptr; - - shm_->close(); - shm_->release(); - } - shm_ = nullptr; - - return ipc_wrapper::stop(); - } - -}; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ipc_wrapper -ipc_wrapper::ipc_wrapper(event_handler* handler) : handler_(handler) -{ - if (handler_) - handler_->add_ref(); -} -ipc_wrapper::~ipc_wrapper() -{} - -void* ipc_wrapper::get_kbuf(size_t* bytes) -{ - if (bytes) - *bytes = 0; - - return nullptr; -} -void ipc_wrapper::release_kbuf(void* buf) -{} -void ipc_wrapper::clear_kernel_objects(void) -{} -bool ipc_wrapper::cancel_write(void) -{ - return false; -} -int32_t ipc_wrapper::stop(void) -{ - if (handler_) - handler_->release(); - handler_ = nullptr; - - return 0; -} - -ipc_wrapper* ipc_wrapper::create_ipc(event_handler* handler, ipc_type type, const char* param) -{ - if (type == IPC_SHARED_MEM) - { - // path-file:id:size[:write-ratio-> percent of size of sent buffer, default is 50, only valid in owner] - std::string file(param); - size_t pos = file.rfind(':'); - std::vector params; - - while(pos != std::string::npos && params.size() < 3) - { - params.push_back(std::stold(file.substr(pos + 1))); - file.erase(pos); - pos = file.rfind(':'); - } - if(params.size() >= 2) - { - params.insert(params.begin(), 50); - pos = params.size(); - - return dynamic_cast(new ipc_wrapper_shm(file.c_str(), params[pos - 1], params[pos - 2], handler, params[pos - 3])); - } - } - return nullptr; -} diff --git a/device/gxx-linux/usb/src/common/ipc_wrapper.h b/device/gxx-linux/usb/src/common/ipc_wrapper.h deleted file mode 100644 index 1263de0..0000000 --- a/device/gxx-linux/usb/src/common/ipc_wrapper.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -// IPC utility -// -// created on 2022-12-02 -// - - -#include "event_monitor.h" - - -class ipc_wrapper : public parent_holder -{ -protected: - event_handler* handler_; - -public: - ipc_wrapper(event_handler* handler); - - enum ipc_type - { - IPC_FILE = 0, // param: path file - IPC_PIPE, // param: pipe name - IPC_NET, // param: dot-ip:port - IPC_SHARED_MEM, // param: path-file:id:size[:write-ratio-> percent of size of sent buffer, default is 50, only valid in owner] - IPC_USB, // param: vid:pid - IPC_COM, // param: COM1 - }; - static ipc_wrapper* create_ipc(event_handler* handler, ipc_type type, const char* param); - -protected: - virtual ~ipc_wrapper(); - -public: - // Function: write content to peer - // - // Parameters: pack - content pack - // - // bytes - [in] bytes of data in 'pack', [out] - bytes of data has sent - // - // kbuf - whether memory 'pack' is from IPC, i.e. return from method get_kbuf() - // - // timeout - time out, in milliseconds - // - // Return: 0 - success - // ENOTCONN - the commuction is not connected, equal to !is_ok() - // EDEADLOCK - calling from current thread is disallowed - // ETIME - time out - // ECANCELED - user cancelled the operation - virtual int32_t write(const char* pack, size_t *bytes, bool kbuf, unsigned timeout = WAIT_INFINITE) = 0; // DON'T call in event_handler::on_event routine, it will be DEAD-LOCK !!! - virtual bool is_ok(void) = 0; // whether the commuction is ready - virtual bool is_first(void) = 0; // whether the communication established by me - - // Function: obtain IPC internal buffer to reduce ONE memory copy for sent data - // - // Parameter: bytes - [in] desired size; [out] - real size - // - // Return: memory pointer if success, or nullptr. call release_kbuf(ptr) if no longer used - virtual void* get_kbuf(size_t* bytes); - virtual void release_kbuf(void* buf); // release the internal buffer returned by get_kbuf - virtual void clear_kernel_objects(void); // clear all kernel objects the IPC used, used to clear exception - virtual bool cancel_write(void); // cancel current write operation - virtual int32_t stop(void) override; // close the connection -}; diff --git a/device/gxx-linux/usb/src/common/json/cJSON.c b/device/gxx-linux/usb/src/common/json/cJSON.c deleted file mode 100644 index cd60134..0000000 --- a/device/gxx-linux/usb/src/common/json/cJSON.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - Copyright (c) 2009 Dave Gamble - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* cJSON */ -/* JSON parser in C. */ - -#include -#include -#include -#include -#include -#include -#include -#include "cJSON.h" - -static const char *ep; - -const char *cJSON_GetErrorPtr(void) {return ep;} - -static int cJSON_strcasecmp(const char *s1,const char *s2) -{ - if (!s1) return (s1==s2)?0:1;if (!s2) return 1; - for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; - return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); -} - -static void* ask_memory(size_t bytes) -{ -// printf("allocate %u bytes memory in cJSON\n", bytes); - - return malloc(bytes); -} -static void *(*cJSON_malloc)(size_t sz) = ask_memory; -static void (*cJSON_free)(void *ptr) = free; - -static char* cJSON_strdup(const char* str) -{ - size_t len; - char* copy; - - len = strlen(str) + 1; - if (!(copy = (char*)cJSON_malloc(len))) return 0; - memcpy(copy,str,len); - return copy; -} - -void cJSON_InitHooks(cJSON_Hooks* hooks) -{ - if (!hooks) { /* Reset hooks */ - cJSON_malloc = ask_memory; - cJSON_free = free; - return; - } - - cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:ask_memory; - cJSON_free = (hooks->free_fn)?hooks->free_fn:free; -} - -/* Internal constructor. */ -static cJSON *cJSON_New_Item(void) -{ - cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); - if (node) memset(node,0,sizeof(cJSON)); - return node; -} - -/* Delete a cJSON structure. */ -void cJSON_Delete(cJSON *c) -{ - cJSON *next; - while (c) - { - next=c->next; - if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); - if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); - if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string); - cJSON_free(c); - c=next; - } -} - -/* Parse the input text to generate a number, and populate the result into item. */ -static const char *parse_number(cJSON *item,const char *num) -{ - double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; - - if (*num=='-') sign=-1,num++; /* Has sign? */ - if (*num=='0') num++; /* is zero */ - if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ - if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ - if (*num=='e' || *num=='E') /* Exponent? */ - { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ - while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ - } - - n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ - - item->valuedouble=n; - item->valueint=(int)n; - item->type=cJSON_Number; - return num; -} - -static int pow2gt (int x) { --x; x|=x>>1; x|=x>>2; x|=x>>4; x|=x>>8; x|=x>>16; return x+1; } - -typedef struct {char *buffer; int length; int offset; } printbuffer; - -static char* ensure(printbuffer *p,int needed) -{ - char *newbuffer;int newsize; - if (!p || !p->buffer) return 0; - needed+=p->offset; - if (needed<=p->length) return p->buffer+p->offset; - - newsize=pow2gt(needed); - newbuffer=(char*)cJSON_malloc(newsize); - if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;} - if (newbuffer) memcpy(newbuffer,p->buffer,p->length); - cJSON_free(p->buffer); - p->length=newsize; - p->buffer=newbuffer; - return newbuffer+p->offset; -} - -static int update(printbuffer *p) -{ - char *str; - if (!p || !p->buffer) return 0; - str=p->buffer+p->offset; - return p->offset+strlen(str); -} - -/* Render the number nicely from the given item into a string. */ -static char *print_number(cJSON *item,printbuffer *p) -{ - char *str=0; - double d=item->valuedouble; - if (d==0) - { - if (p) str=ensure(p,2); - else str=(char*)cJSON_malloc(2); /* special case for 0. */ - if (str) strcpy(str,"0"); - } - else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) - { - if (p) str=ensure(p,21); - else str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ - if (str) sprintf(str,"%d",item->valueint); - } - else - { - if (p) str=ensure(p,64); - else str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ - if (str) - { - if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); - else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); - else sprintf(str,"%f",d); - } - } - return str; -} - -static unsigned parse_hex4(const char *str) -{ - unsigned h=0; - if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; - h=h<<4;str++; - if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; - h=h<<4;str++; - if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; - h=h<<4;str++; - if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; - return h; -} - -/* Parse the input text into an unescaped cstring, and populate item. */ -static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; -static const char *parse_string(cJSON *item,const char *str) -{ - const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; - if (*str!='\"') {ep=str;return 0;} /* not a string! */ - - while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ - - out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ - if (!out) return 0; - - ptr=str+1;ptr2=out; - while (*ptr!='\"' && *ptr) - { - if (*ptr!='\\') *ptr2++=*ptr++; - else - { - ptr++; - switch (*ptr) - { - case 'b': *ptr2++='\b'; break; - case 'f': *ptr2++='\f'; break; - case 'n': *ptr2++='\n'; break; - case 'r': *ptr2++='\r'; break; - case 't': *ptr2++='\t'; break; - case 'u': /* transcode utf16 to utf8. */ - uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */ - - if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */ - - if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */ - { - if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */ - uc2=parse_hex4(ptr+3);ptr+=6; - if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ - uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); - } - - len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; - - switch (len) { - case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 1: *--ptr2 =(uc | firstByteMark[len]); - } - ptr2+=len; - break; - default: *ptr2++=*ptr; break; - } - ptr++; - } - } - *ptr2=0; - if (*ptr=='\"') ptr++; - item->valuestring=out; - item->type=cJSON_String; - return ptr; -} -char* cJSON_utf8_2_unic(const char* utf8) -{ - char* unic = (char*)malloc(strlen(utf8) * 3 + 8); - unsigned char * cur = unic; - - while (*cur = *utf8++) - { - if ((*cur & 0x0f0) == 0x0e0) - { - if (((unsigned char)utf8[0] & 0x0c0) == 0x80 && - ((unsigned char)utf8[1] & 0x0c0) == 0x80) - { - char* hex = "0123456789ABCDEF"; - unsigned short us = *cur & 0x0f; - us <<= 6; - us += utf8[0] & 0x3f; - us <<= 6; - us += utf8[1] & 0x3f; - - *cur++ = '\\'; - *cur++ = 'u'; - cur[3] = hex[us & 0x0f]; - us >>= 4; - cur[2] = hex[us & 0x0f]; - us >>= 4; - cur[1] = hex[us & 0x0f]; - us >>= 4; - cur[0] = hex[us & 0x0f]; - cur += 3; - utf8 += 2; - } - } - cur++; - } - *cur++ = 0; - - return unic; -} - -/* Render the cstring provided to an escaped version that can be printed. */ -static char *print_string_ptr(const char *str,printbuffer *p) -{ - const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token; - - for (ptr=str;*ptr;ptr++) flag|=((*ptr>0 && *ptr<32)||(*ptr=='\"')||(*ptr=='\\'))?1:0; - if (!flag) - { - len=ptr-str; - if (p) out=ensure(p,len+3); - else out=(char*)cJSON_malloc(len+3); - if (!out) return 0; - ptr2=out;*ptr2++='\"'; - strcpy(ptr2,str); - ptr2[len]='\"'; - ptr2[len+1]=0; - return out; - } - - if (!str) - { - if (p) out=ensure(p,3); - else out=(char*)cJSON_malloc(3); - if (!out) return 0; - strcpy(out,"\"\""); - return out; - } - ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} - - if (p) out=ensure(p,len+3); - else out=(char*)cJSON_malloc(len+3); - if (!out) return 0; - - ptr2=out;ptr=str; - *ptr2++='\"'; - while (*ptr) - { - if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; - else - { - *ptr2++='\\'; - switch (token=*ptr++) - { - case '\\': *ptr2++='\\'; break; - case '\"': *ptr2++='\"'; break; - case '\b': *ptr2++='b'; break; - case '\f': *ptr2++='f'; break; - case '\n': *ptr2++='n'; break; - case '\r': *ptr2++='r'; break; - case '\t': *ptr2++='t'; break; - default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ - } - } - } - *ptr2++='\"';*ptr2++=0; - return out; -} -/* Invote print_string_ptr (which is useful) on an item. */ -static char *print_string(cJSON *item,printbuffer *p) {return print_string_ptr(item->valuestring,p);} - -/* Predeclare these prototypes. */ -static const char *parse_value(cJSON *item,const char *value); -static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p); -static const char *parse_array(cJSON *item,const char *value); -static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p); -static const char *parse_object(cJSON *item,const char *value); -static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p); - -/* Utility to jump whitespace and cr/lf */ -static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} - -/* Parse an object - create a new root, and populate. */ -cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) -{ - const char *end=0; - cJSON *c=cJSON_New_Item(); - ep=0; - if (!c) return 0; /* memory fail */ - - end=parse_value(c,skip(value)); - if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */ - - /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ - if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} - if (return_parse_end) *return_parse_end=end; - return c; -} -/* Default options for cJSON_Parse */ -cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} - -/* Render a cJSON item/entity/structure to text. */ -char *cJSON_Print(cJSON *item) {return print_value(item,0,1,0);} -char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0,0);} - -char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt) -{ - printbuffer p; - p.buffer=(char*)cJSON_malloc(prebuffer); - p.length=prebuffer; - p.offset=0; - return print_value(item,0,fmt,&p); - return p.buffer; -} - - -/* Parser core - when encountering text, process appropriately. */ -static const char *parse_value(cJSON *item,const char *value) -{ - if (!value) return 0; /* Fail on null. */ - if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } - if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } - if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } - if (*value=='\"') { return parse_string(item,value); } - if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } - if (*value=='[') { return parse_array(item,value); } - if (*value=='{') { return parse_object(item,value); } - - ep=value;return 0; /* failure. */ -} - -/* Render a value to text. */ -static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p) -{ - char *out=0; - if (!item) return 0; - if (p) - { - switch ((item->type)&255) - { - case cJSON_NULL: {out=ensure(p,5); if (out) strcpy(out,"null"); break;} - case cJSON_False: {out=ensure(p,6); if (out) strcpy(out,"false"); break;} - case cJSON_True: {out=ensure(p,5); if (out) strcpy(out,"true"); break;} - case cJSON_Number: out=print_number(item,p);break; - case cJSON_String: out=print_string(item,p);break; - case cJSON_Array: out=print_array(item,depth,fmt,p);break; - case cJSON_Object: out=print_object(item,depth,fmt,p);break; - } - } - else - { - switch ((item->type)&255) - { - case cJSON_NULL: out=cJSON_strdup("null"); break; - case cJSON_False: out=cJSON_strdup("false");break; - case cJSON_True: out=cJSON_strdup("true"); break; - case cJSON_Number: out=print_number(item,0);break; - case cJSON_String: out=print_string(item,0);break; - case cJSON_Array: out=print_array(item,depth,fmt,0);break; - case cJSON_Object: out=print_object(item,depth,fmt,0);break; - } - } - return out; -} - -/* Build an array from input text. */ -static const char *parse_array(cJSON *item,const char *value) -{ - cJSON *child; - if (*value!='[') {ep=value;return 0;} /* not an array! */ - - item->type=cJSON_Array; - value=skip(value+1); - if (*value==']') return value+1; /* empty array. */ - - item->child=child=cJSON_New_Item(); - if (!item->child) return 0; /* memory fail */ - value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ - if (!value) return 0; - - while (*value==',') - { - cJSON *new_item; - if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ - child->next=new_item;new_item->prev=child;child=new_item; - value=skip(parse_value(child,skip(value+1))); - if (!value) return 0; /* memory fail */ - } - - if (*value==']') return value+1; /* end of array */ - ep=value;return 0; /* malformed. */ -} - -/* Render an array to text */ -static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p) -{ - char **entries; - char *out=0,*ptr,*ret;int len=5; - cJSON *child=item->child; - int numentries=0,i=0,fail=0; - size_t tmplen=0; - - /* How many entries in the array? */ - while (child) numentries++,child=child->next; - /* Explicitly handle numentries==0 */ - if (!numentries) - { - if (p) out=ensure(p,3); - else out=(char*)cJSON_malloc(3); - if (out) strcpy(out,"[]"); - return out; - } - - if (p) - { - /* Compose the output array. */ - i=p->offset; - ptr=ensure(p,1);if (!ptr) return 0; *ptr='['; p->offset++; - child=item->child; - while (child && !fail) - { - print_value(child,depth+1,fmt,p); - p->offset=update(p); - if (child->next) {len=fmt?2:1;ptr=ensure(p,len+1);if (!ptr) return 0;*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;p->offset+=len;} - child=child->next; - } - ptr=ensure(p,2);if (!ptr) return 0; *ptr++=']';*ptr=0; - out=(p->buffer)+i; - } - else - { - /* Allocate an array to hold the values for each */ - entries=(char**)cJSON_malloc(numentries*sizeof(char*)); - if (!entries) return 0; - memset(entries,0,numentries*sizeof(char*)); - /* Retrieve all the results: */ - child=item->child; - while (child && !fail) - { - ret=print_value(child,depth+1,fmt,0); - entries[i++]=ret; - if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; - child=child->next; - } - - /* If we didn't fail, try to ask_memory the output string */ - if (!fail) out=(char*)cJSON_malloc(len); - /* If that fails, we fail. */ - if (!out) fail=1; - - /* Handle failure. */ - if (fail) - { - for (i=0;itype=cJSON_Object; - value=skip(value+1); - if (*value=='}') return value+1; /* empty array. */ - - item->child=child=cJSON_New_Item(); - if (!item->child) return 0; - value=skip(parse_string(child,skip(value))); - if (!value) return 0; - child->string=child->valuestring;child->valuestring=0; - if (*value!=':') {ep=value;return 0;} /* fail! */ - value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ - if (!value) return 0; - - while (*value==',') - { - cJSON *new_item; - if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ - child->next=new_item;new_item->prev=child;child=new_item; - value=skip(parse_string(child,skip(value+1))); - if (!value) return 0; - child->string=child->valuestring;child->valuestring=0; - if (*value!=':') {ep=value;return 0;} /* fail! */ - value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ - if (!value) return 0; - } - - if (*value=='}') return value+1; /* end of array */ - ep=value;return 0; /* malformed. */ -} - -/* Render an object to text. */ -static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p) -{ - char **entries=0,**names=0; - char *out=0,*ptr,*ret,*str;int len=7,i=0,j; - cJSON *child=item->child; - int numentries=0,fail=0; - size_t tmplen=0; - /* Count the number of entries. */ - while (child) numentries++,child=child->next; - /* Explicitly handle empty object case */ - if (!numentries) - { - if (p) out=ensure(p,fmt?depth+4:3); - else out=(char*)cJSON_malloc(fmt?depth+4:3); - if (!out) return 0; - ptr=out;*ptr++='{'; - if (fmt) {*ptr++='\n';for (i=0;ioffset; - len=fmt?2:1; ptr=ensure(p,len+1); if (!ptr) return 0; - *ptr++='{'; if (fmt) *ptr++='\n'; *ptr=0; p->offset+=len; - child=item->child;depth++; - while (child) - { - if (fmt) - { - ptr=ensure(p,depth); if (!ptr) return 0; - for (j=0;joffset+=depth; - } - print_string_ptr(child->string,p); - p->offset=update(p); - - len=fmt?2:1; - ptr=ensure(p,len); if (!ptr) return 0; - *ptr++=':';if (fmt) *ptr++='\t'; - p->offset+=len; - - print_value(child,depth,fmt,p); - p->offset=update(p); - - len=(fmt?1:0)+(child->next?1:0); - ptr=ensure(p,len+1); if (!ptr) return 0; - if (child->next) *ptr++=','; - if (fmt) *ptr++='\n';*ptr=0; - p->offset+=len; - child=child->next; - } - ptr=ensure(p,fmt?(depth+1):2); if (!ptr) return 0; - if (fmt) for (i=0;ibuffer)+i; - } - else - { - /* Allocate space for the names and the objects */ - entries=(char**)cJSON_malloc(numentries*sizeof(char*)); - if (!entries) return 0; - names=(char**)cJSON_malloc(numentries*sizeof(char*)); - if (!names) {cJSON_free(entries);return 0;} - memset(entries,0,sizeof(char*)*numentries); - memset(names,0,sizeof(char*)*numentries); - - /* Collect all the results into our arrays: */ - child=item->child;depth++;if (fmt) len+=depth; - while (child) - { - names[i]=str=print_string_ptr(child->string,0); - entries[i++]=ret=print_value(child,depth,fmt,0); - if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; - child=child->next; - } - - /* Try to allocate the output string */ - if (!fail) out=(char*)cJSON_malloc(len); - if (!out) fail=1; - - /* Handle failure */ - if (fail) - { - for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} -cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} -cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} - -/* Utility for array list handling. */ -static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} -/* Utility for handling references. */ -static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} - -/* Add item to array/object. */ -void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} -void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} -void cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (!(item->type&cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string=(char*)string;item->type|=cJSON_StringIsConst;cJSON_AddItemToArray(object,item);} -void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} -void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} - -cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; - if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} -void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} -cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} -void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} - -/* Replace array/object items with new ones. */ -void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) {cJSON_AddItemToArray(array,newitem);return;} - newitem->next=c;newitem->prev=c->prev;c->prev=newitem;if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;} -void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; - newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; - if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} -void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} - -/* Create basic types: */ -cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} -cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} -cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} -cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} -cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} -cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} -cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} -cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} - -/* Create Arrays: */ -cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} - -/* Duplication */ -cJSON *cJSON_Duplicate(cJSON *item,int recurse) -{ - cJSON *newitem,*cptr,*nptr=0,*newchild; - /* Bail on bad ptr */ - if (!item) return 0; - /* Create new item */ - newitem=cJSON_New_Item(); - if (!newitem) return 0; - /* Copy over all vars */ - newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; - if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}} - if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}} - /* If non-recursive, then we're done! */ - if (!recurse) return newitem; - /* Walk the ->next chain for the child. */ - cptr=item->child; - while (cptr) - { - newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */ - if (!newchild) {cJSON_Delete(newitem);return 0;} - if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */ - else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */ - cptr=cptr->next; - } - return newitem; -} - -void cJSON_Minify(char *json) -{ - char *into=json; - while (*json) - { - if (*json==' ') json++; - else if (*json=='\t') json++; /* Whitespace characters. */ - else if (*json=='\r') json++; - else if (*json=='\n') json++; - else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; /* double-slash comments, to end of line. */ - else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} /* multiline comments. */ - else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} /* string literals, which are \" sensitive. */ - else *into++=*json++; /* All other characters. */ - } - *into=0; /* and null-terminate. */ -} diff --git a/device/gxx-linux/usb/src/common/referer.cpp b/device/gxx-linux/usb/src/common/referer.cpp deleted file mode 100644 index 799b303..0000000 --- a/device/gxx-linux/usb/src/common/referer.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "referer.h" - -#include - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// refer -refer::refer() : ref_(1) -{ - on_born(); -} -refer::~refer() -{ - on_dead(); -} - -void refer::on_born(void) -{} -void refer::on_dead(void) -{} - -int32_t refer::add_ref(void) -{ - LOCKER lock(mutex_); - - return ++ref_; -} -int32_t refer::release(void) -{ - int32_t ref = 0; - - { - LOCKER lock(mutex_); - ref = --ref_; - } - - if (ref == 0) - delete this; - - return ref; -} - - - - - - - - - - - - - - - - - - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// chronograph -#if defined(WIN32) || defined(_WIN64) -// #define WIN32_LEAN_AND_MEAN -#include -#include - -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 // microseconds from '1601-01-01 00:00:00' to '1970-01-01 00:00:00' - -int gettimeofday(TIMEV* tv, struct timezone* tz) -{ - FILETIME ft = { 0 }; - uint64_t ui64 = 0; - static bool set_tz = true; - - GetSystemTimeAsFileTime(&ft); // 100 ns - from 1601-01-01 00:00:00 - ui64 = ft.dwHighDateTime; - ui64 <<= 32; - ui64 |= ft.dwLowDateTime; - - // convert to microseconds ... - ui64 += 5; - ui64 /= 10; - - // move to 1970-01-01 00:00:00 - ui64 -= DELTA_EPOCH_IN_MICROSECS; - if (tv) - { - tv->tv_sec = ui64 / 1000000; - tv->tv_usec = ui64 % 1000000; - } - - if (tz) - { - if (set_tz) - { - set_tz = false; - _tzset(); - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - - return 0; -} - -#endif - -chronograph::chronograph() -{ - reset(); -} -chronograph::~chronograph() -{} - -bool chronograph::now(TIMEV* tv) -{ - struct timezone tz = { 0 }; - - return gettimeofday(tv, &tz) == 0; -} -bool chronograph::now(uint64_t* seconds, uint64_t* u_seconds) -{ - TIMEV tv = { 0 }; - struct timezone tz = { 0 }; - - if (gettimeofday(&tv, &tz) == 0) - { - if (seconds) - *seconds = tv.tv_sec; - if (u_seconds) - *u_seconds = tv.tv_usec; - - return true; - } - else - { - return false; - } -} -std::string chronograph::now(bool with_ms/*whether with milliseconds*/) // return '2022-11-30 10:38:42.123', no '.123' if with_ms was false -{ - TIMEV tv = { 0 }; - - if (!chronograph::now(&tv)) - return ""; - - char buf[40] = { 0 }; - time_t t = tv.tv_sec; - struct tm* l = localtime(&t); - - if (with_ms) - sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d.%06d", l->tm_year + 1900, l->tm_mon + 1, l->tm_mday - , l->tm_hour, l->tm_min, l->tm_sec, tv.tv_usec); - else - sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d", l->tm_year + 1900, l->tm_mon + 1, l->tm_mday - , l->tm_hour, l->tm_min, l->tm_sec); - - return buf; -} - -uint64_t chronograph::elapse_s(void) -{ - TIMEV tv = { 0 }; - - chronograph::now(&tv); - - return tv.tv_sec - bgn_.tv_sec; -} -uint64_t chronograph::elapse_ms(void) -{ - TIMEV tv = { 0 }; - uint64_t dif = 0; - - chronograph::now(&tv); - dif = SEC_2_MS(tv.tv_sec - bgn_.tv_sec); - dif += tv.tv_usec / MSEC_2_US(1); - dif -= bgn_.tv_usec / MSEC_2_US(1); - - return dif; -} -uint64_t chronograph::elapse_us(void) -{ - TIMEV tv = { 0 }; - uint64_t dif = 0; - - chronograph::now(&tv); - dif = SEC_2_US(tv.tv_sec - bgn_.tv_sec); - dif += tv.tv_usec; - dif -= bgn_.tv_usec; - - return dif; -} -void chronograph::reset() -{ - chronograph::now(&bgn_); -} - - - diff --git a/device/gxx-linux/usb/src/common/sane_cfg.cpp b/device/gxx-linux/usb/src/common/sane_cfg.cpp deleted file mode 100644 index b84c9a3..0000000 --- a/device/gxx-linux/usb/src/common/sane_cfg.cpp +++ /dev/null @@ -1,374 +0,0 @@ -#include "sane_cfg.h" - -#include "json/json.h" - - - - - - - - - - - - - - - - - - - - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// sane_cfg_provider: -sane_cfg_provider::sane_cfg_provider() -{} -sane_cfg_provider::~sane_cfg_provider() -{} - -std::string sane_cfg_provider::sane_option_value_get(json* jsn, const char* key, std::string* strval) -{ - std::string type(""), ret(""); - - if (jsn->get_value("type", type)) - { - if (type == "bool") - { - bool v = false; - if (jsn->get_value(key, v)) - ret = std::string((char*)&v, sizeof(v)); - if(strval) - *strval = v ? "true" : "false"; - } - else if (type == "int") - { - int v = 0; - if (jsn->get_value(key, v)) - ret = std::string((char*)&v, sizeof(v)); - if(strval) - *strval = std::to_string(v); - } - else if (type == "float") - { - double v = false; - if (jsn->get_value(key, v)) - ret = std::string((char*)&v, sizeof(v)); - if(strval) - { - char buf[80] = {0}; - sprintf(buf, "%f", v); - *strval = buf; - } - } - else - { - jsn->get_value(key, ret); - if(strval) - *strval = ret; - } - } - - return std::move(ret); -} -bool sane_cfg_provider::sane_option_value_set(json* jsn, void* data, const char* key) -{ - std::string type(""); - bool ret = jsn->get_value("type", type); - - if (ret) - { - if (type == "bool") - { - ret = jsn->set_value(key, *(bool*)data); - } - else if (type == "int") - { - ret = jsn->set_value(key, *(int*)data); - } - else if (type == "float") - { - ret = jsn->set_value(key, *(double*)data); - } - else - { - ret = jsn->set_value(key, (char*)data); - } - } - - 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; -} - - - - - - - - - - - - - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// : - -sane_cfg_mgr::sane_cfg_mgr() -{} -sane_cfg_mgr::~sane_cfg_mgr() -{ - cfg_api_.clear(); - for (auto& v : sane_waiters_) - v->release(); - sane_waiters_.clear(); -} - -json* sane_cfg_mgr::load_all_configs(sane_cfg_provider* prvd) -{ - char * buf = nullptr; - size_t len = 0; - int32_t err = prvd->get_config(buf, &len); - json * jsn = nullptr; - - if (err == ENOMEM) - { - len = ALIGN_INT(len, 8); - buf = (char*)malloc(len); - if (buf) - { - err = prvd->get_config(buf, &len); - if (err == 0) - { - jsn = new json(); - if(!jsn->attach_text(buf)) - { - jsn->release(); - jsn = nullptr; - } - } - free(buf); - } - } - - return jsn; -} - -void sane_cfg_mgr::add_sane_api(const char* name, int ver, sane_cfg_provider* prvd) -{ - if (cfg_api_.count(name) && cfg_api_[name].ver >= ver) - return; - - cfg_api_[name].prvd = prvd; -} -void sane_cfg_mgr::refresh_api(sane_cfg_provider* prvd, std::vector* given) -{ - char * buf = nullptr; - size_t len = 0; - json *jsn = sane_cfg_mgr::load_all_configs(prvd), *child = nullptr; - - if (!jsn) - return; - - if (given) - { - for (auto& v : *given) - { - if (jsn->get_value(v.c_str(), child) && child) - { - int ver = 0; - if (child->get_value("ver", ver)) - add_sane_api(v.c_str(), ver, prvd); - child->release(); - } - } - } - else - { - child = jsn->first_child(); - while (child) - { - int ver = 0; - if (child->get_value("ver", ver)) - add_sane_api(child->key().c_str(), ver, prvd); - child = jsn->next_child(); - } - } - jsn->release(); -} -void sane_cfg_mgr::on_sane_provider_changed(sane_cfg_provider* prvd, bool add) -{ - if (add) - { - refresh_api(prvd); - } - else - { - std::vector lost; - for (auto& v : cfg_api_) - { - if (v.second.prvd == prvd) - lost.push_back(v.first); - } - for (auto& v : lost) - cfg_api_.erase(v); - - char *buf = nullptr; - size_t size = 0, len = 0; - int32_t err = 0; - - for (auto& v : sane_waiters_) - { - refresh_api(v, &lost); - } - } -} -std::string sane_cfg_mgr::get_all_configurations(void) -{ - std::map jsns; - json* all = new json(), * child = nullptr; - std::string text(""); - - for (auto& v : sane_waiters_) - { - json* jsn = sane_cfg_mgr::load_all_configs(v); - if (jsn) - jsns[v] = jsn; - } - for (auto& v : cfg_api_) - { - if (jsns.count(v.second.prvd)) - { - if (jsns[v.second.prvd]->get_value(v.first.c_str(), child) && child) - { - all->set_value(v.first.c_str(), child); - child->release(); - } - } - } - text = all->to_string(); - all->release(); - - for (auto& v : jsns) - v.second->release(); - jsns.clear(); - - return std::move(text); -} - -int sane_cfg_mgr::reg_sane_provider(sane_cfg_provider* prvd) -{ - LOCKER lock(locker_); - if (std::find(sane_waiters_.begin(), sane_waiters_.end(), prvd) == sane_waiters_.end()) - { - sane_waiters_.push_back(prvd); - prvd->add_ref(); - on_sane_provider_changed(prvd, true); - - return 0; - } - - return EEXIST; -} -int sane_cfg_mgr::unreg_sane_provider(sane_cfg_provider* prvd) -{ - LOCKER lock(locker_); - std::vector::iterator it = std::find(sane_waiters_.begin(), sane_waiters_.end(), prvd); - - if (it == sane_waiters_.end()) - return ENOENT; - - sane_waiters_.erase(it); - on_sane_provider_changed(prvd, false); - prvd->release(); - - return 0; -} - -// following APIs' parameters are same as sane_cfg_provider ... -int32_t sane_cfg_mgr::get_config(std::string& text, const char* cfg_name, std::string* str) -{ - if (cfg_name) - { - if (*cfg_name && cfg_api_.count(cfg_name)) - { - size_t len = 0; - int32_t err = cfg_api_[cfg_name].prvd->get_config(nullptr, &len, cfg_name, str); - - if (err == ENOMEM) - { - text.resize(len + 1); - err = cfg_api_[cfg_name].prvd->get_config(&text[0], &len, cfg_name, str); - text.resize(len); - } - - return err; - } - else - return ENOENT; - } - else - { - // get all ... - text = std::move(get_all_configurations()); - - return 0; - } -} -int32_t sane_cfg_mgr::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) -{ - if (cfg_name) - { - if (cfg_api_.count(cfg_name)) - return cfg_api_[cfg_name].prvd->set_config(cfg_name, data, len, afterdo); - else - return ENOENT; - } - else - return EINVAL; -} - diff --git a/device/gxx-linux/usb/src/hardware/hardware.cpp b/device/gxx-linux/usb/src/hardware/hardware.cpp deleted file mode 100644 index 074583a..0000000 --- a/device/gxx-linux/usb/src/hardware/hardware.cpp +++ /dev/null @@ -1,432 +0,0 @@ -#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 deleted file mode 100644 index a257def..0000000 --- a/device/gxx-linux/usb/src/hardware/hardware.h +++ /dev/null @@ -1,56 +0,0 @@ -#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 990beb2..83cf57e 100644 --- a/device/gxx-linux/usb/src/usbdevice.cpp +++ b/device/gxx-linux/usb/src/usbdevice.cpp @@ -11,12 +11,20 @@ #include #include -#include "log_util.h" #ifdef ASYNC_EP #include "common/sys_util.h" -#include "common/json/json.h" -#include "hardware/hardware.h" -#include "commondef.h" +#include "common/json/gb_json.h" +#include "common/log_util.h" +#include "scanner/async_scanner.h" + +#ifdef TEMPORARY_API +int32_t (*scan_start)(void) = nullptr; +int32_t (*scan_stop)(void) = nullptr; +int32_t (*set_dpi)(int*, int*) = nullptr; +int32_t (*set_scan_num)(int) = nullptr; +int32_t (*set_image_receiver)(void(*rcv)(int data_type, void* data, size_t w, size_t h, int, int, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, void* param), void* param) = nullptr; +#endif + #endif #define CONFIG_VALUE 1 @@ -65,6 +73,29 @@ static std::shared_ptr bulk_read_; static std::shared_ptr int_sent_; const int UsbDevice::cacheSize = 64*1024; +#ifdef TEMPORARY_API +static UsbDevice* inst = nullptr; +int32_t call_start_scan(void) +{ + return inst->start_scan(); +} +int32_t call_stop_scan(void) +{ + return inst->stop_scan(); +} +int32_t call_set_dpi(int* dpix, int* dpiy) +{ + return inst->set_dpi(dpix, dpiy); +} +int32_t call_set_scan_num(int num) +{ + return inst->set_scan_num(num); +} +int32_t call_set_image_receiver(void(*rcv)(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, void* param), void* param) +{ + return inst->set_img_receiver((void*)rcv, param); +} +#endif int camtp_load_config_file(camtp_ctx * context, const char * conffile) @@ -315,23 +346,11 @@ void UsbDevice::fill_dev_descriptor(camtp_ctx * ctx, usb_gadget * usbctx,struct return; } -#ifdef ASYNC_EP -static void print_mem_usage(const char* desc) -{ - uint64_t size = sys_util::get_memory_usage("scan"); - - printf("\n--Memory usage of %s: %s--\n", desc, sys_util::format_readable_bytes(size).c_str()); -} -static void image_receiver(MemoryPtr data, bool img, void* param) -{ - ((UsbDevice*)param)->save_image(data, img); -} -#endif UsbDevice::UsbDevice(std::function handler, std::function call_back) : b_connected(false) , connect_call(call_back) #ifdef ASYNC_EP -, usb_(nullptr), cfg_(nullptr), scan_over_pack_(nullptr), scan_id_(0) +, ascan_(nullptr) #endif { camtp_context.reset(new camtp_ctx); @@ -339,59 +358,22 @@ UsbDevice::UsbDevice(std::function dyn_mem_ptr - { - LPPACK_BASE pack = (LPPACK_BASE)data->ptr(); - uint32_t consume = 0, want = 0; - - if(!used) - used = &consume; - *used = data->get_rest(); - - return handle_bulk_cmd(pack, used, required); - }; - - auto ctrl_unhandle = [&](struct usb_functionfs_event* pev) -> dyn_mem_ptr - { - return unhandled_ep0(pev); - }; - - auto on_connect = [&](bool conn) -> void - { - static bool reg_cb = true; - - if(reg_cb) - { - uint64_t cb[] = {(uint64_t)image_receiver, (uint64_t)this}; - ctrl_handler(-1, (usb_ctrlrequest*)-1, (unsigned char*)cb); - - reg_cb = false; - } - - connect_call(conn); - }; + ::inst = this; + ::scan_start = call_start_scan; + ::scan_stop = call_stop_scan; + ::set_dpi = call_set_dpi; + ::set_scan_num = call_set_scan_num; + ::set_image_receiver = call_set_image_receiver; thread_pool *t = new thread_pool(this); - print_mem_usage("new thread_pool"); t->thread_new(&UsbDevice::do_system_command, R"(echo linaro | sudo -S sh -c "echo fe900000.dwc3 > /opt/cfg/usb_gadget/g1/UDC")"); camtp_load_config_file(camtp_context.get(), ""); - // std::this_thread::sleep_for(std::chrono::milliseconds(50)); usb_ctx = init_usb_camtp_gadget(camtp_context.get()); - print_mem_usage("init_usb_camtp_gadget"); if(usb_ctx && usb_ctx->usb_device >= 0) { get_system_output(R"(echo linaro | sudo -S sh -c "chmod 777 /dev/ffs-camtp -R")"); init_eps(usb_ctx, camtp_context->usb_cfg.usb_functionfs_mode, false); - print_mem_usage("init_eps"); - - usb_ = new async_usb_gadget(usb_ctx, ctrl_unhandle, bulk_handle, on_connect); - print_mem_usage("new async_usb_gadget"); + ascan_ = new async_scanner(usb_ctx); } t->thread_stop(); t->release(); @@ -406,15 +388,15 @@ UsbDevice::UsbDevice(std::functionstop(); - usb_->release(); + ascan_->stop(); + ascan_->release(); + ascan_ = nullptr; } - if(cfg_) - cfg_->release(); +#else + pthread_cancel(thread_main.native_handle()); #endif } @@ -1400,771 +1382,64 @@ init_eps_error: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // #ifdef ASYNC_EP - -// C2-B0-AF-79-75-D6 -//static std::string img_opt1("{\"is-multiout\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\",\"desc\":\"\\u540c\\u65f6\\u8f93\\u51fa\\u591a\\u79cd\\u989c\\u8272\\u6a21\\u5f0f\\u7684\\u56fe\\u50cf\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"multiout-type\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\\u7c7b\\u578b\",\"desc\":\"\\u9009\\u62e9\\u591a\\u6d41\\u8f93\\u51fa\\u7684\\u7c7b\\u578b\",\"type\":\"string\",\"cur\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"default\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"size\":32,\"range\":[\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"\\u5f69\\u8272+\\u7070\\u5ea6\",\"\\u5f69\\u8272+\\u9ed1\\u767d\",\"\\u7070\\u5ea6+\\u9ed1\\u767d\"],\"depend_or\":[\"is-multiout==true\"]},\"mode\":{\"category\":\"base\",\"readonly\":false,\"affect\":6,\"group\":\"base\",\"visible\":true,\"field\":\"Hardware\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u8272\\u5f69\\u6a21\\u5f0f\",\"type\":\"string\",\"cur\":\"24\\u4f4d\\u5f69\\u8272\",\"default\":\"24\\u4f4d\\u5f69\\u8272\",\"size\":32,\"range\":[\"24\\u4f4d\\u5f69\\u8272\",\"256\\u7ea7\\u7070\\u5ea6\",\"\\u9ed1\\u767d\",\"\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"],\"depend_or\":[\"is-multiout!=true\"]},\"binary-threshold\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u9ed1\\u767d\\u56fe\\u50cf\\u9608\\u503c\",\"desc\":\"\\u9ad8\\u4e8e\\u8be5\\u9608\\u503c\\u4e3a1��\\u767d����\\u4f4e\\u4e8e\\u8be5\\u9608\\u503c\\u4e3a0��\\u9ed1��\",\"type\":\"int\",\"cur\":127,\"default\":127,\"size\":4,\"range\":{\"min\":0,\"max\":255,\"step\":1},\"depend_or\":[\"is-multiout==true\",\"mode==\\u9ed1\\u767d\"]},\"reverse-bw\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u9ed1\\u767d\\u56fe\\u50cf\\u53cd\\u8272\\u8f93\\u51fa\",\"desc\":\"\\u8f93\\u51fa\\u7684\\u9ed1\\u767d\\u56fe\\u50cf\\u4ee5��1��\\u4ee3\\u8868\\u9ed1\\u8272����0��\\u4ee3\\u8868\\u767d\\u8272\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_or\":[\"is-multiout==true\",\"mode==\\u9ed1\\u767d\"]},\"filter\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u7070\\u5ea6\\u6216\\u9ed1\\u767d\\u56fe\\u50cf - \\u9664\\u8272\\u4e0e\\u589e\\u5f3a\",\"desc\":\"\\u6d88\\u9664\\u6216\\u589e\\u5f3a\\u6307\\u5b9a\\u8272\\u5f69\",\"type\":\"string\",\"cur\":\"\\u4e0d\\u9664\\u8272\",\"default\":\"\\u4e0d\\u9664\\u8272\",\"size\":24,\"range\":[\"\\u4e0d\\u9664\\u8272\",\"\\u9664\\u7ea2\\u8272\",\"\\u9664\\u7eff\\u8272\",\"\\u9664\\u84dd\\u8272\",\"\\u7ea2\\u8272\\u589e\\u5f3a\",\"\\u7eff\\u8272\\u589e\\u5f3a\",\"\\u84dd\\u8272\\u589e\\u5f3a\"],\"depend_and\":[\"is-multiout!=true\",\"mode!=24\\u4f4d\\u5f69\\u8272\",\"!=\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"]},\"is-rid-multiout-red\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"24\\u4f4d\\u5f69\\u8272\\u56fe\\u50cf - \\u591a\\u6d41\\u8f93\\u51fa\\u9664\\u7ea2\",\"desc\":\"\\u540c\\u65f6\\u8f93\\u51fa\\u5f69\\u8272\\u56fe\\u50cf\\u548c\\u7070\\u5ea6\\u9664\\u7ea2\\u56fe\\u50cf\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"is-multiout!=true\",\"mode!=256\\u7ea7\\u7070\\u5ea6\",\"!=\\u9ed1\\u767d\",\"!=\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"]},\"is-rid-answer-sheet-red\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"24\\u4f4d\\u5f69\\u8272\\u56fe\\u50cf - \\u7b54\\u9898\\u5361\\u9664\\u7ea2\",\"desc\":\"\\u8f93\\u51fa\\u9664\\u7ea2\\u5f69\\u8272\\u56fe\\u50cf\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"is-multiout!=true\",\"mode!=256\\u7ea7\\u7070\\u5ea6\",\"!=\\u9ed1\\u767d\",\"!=\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"]},\"is-erase-bkg\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u80cc\\u666f\\u79fb\\u9664\",\"desc\":\"\\u79fb\\u9664\\u6587\\u7a3f\\u80cc\\u666f\\u5e95\\u8272\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"is-multiout!=true\",\"mode!=256\\u7ea7\\u7070\\u5ea6\",\"!=\\u9ed1\\u767d\",\"!=\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"]},\"bkg-color-range\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u80cc\\u666f\\u8272\\u5f69\\u6d6e\\u52a8\\u8303\\u56f4\",\"desc\":\"\\u4e0e\\u80cc\\u666f\\u5e95\\u8272\\u504f\\u5dee\\u5728\\u8be5\\u503c\\u8303\\u56f4\\u5185\\u7684\\u989c\\u8272��\\u90fd\\u5c06\\u88ab\\u79fb\\u9664\",\"type\":\"int\",\"cur\":20,\"default\":20,\"size\":4,\"range\":{\"min\":1,\"max\":128,\"step\":1},\"depend_or\":[\"is-erase-bkg==true\"]},\"sharpen\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u9510\\u5316\\u4e0e\\u6a21\\u7cca\",\"desc\":\"\\u9009\\u62e9\\u9510\\u5316\\u6548\\u679c\\u6216\\u6a21\\u7cca\\u6548\\u679c\",\"type\":\"string\",\"cur\":\"\\u65e0\",\"default\":\"\\u65e0\",\"size\":24,\"range\":[\"\\u65e0\",\"\\u9510\\u5316\",\"\\u8fdb\\u4e00\\u6b65\\u9510\\u5316\",\"\\u6a21\\u7cca\",\"\\u8fdb\\u4e00\\u6b65\\u6a21\\u7cca\"],\"depend_and\":[\"is-multiout!=true\",\"mode!=\\u9ed1\\u767d\",\"!=\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"]},\"is-rid-morr\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u53bb\\u9664\\u6469\\u5c14\\u7eb9\",\"desc\":\"\\u53bb\\u9664\\u56fe\\u50cf\\u4e2d\\u7684\\u6469\\u5c14\\u7eb9\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"is-multiout!=true\",\"mode!=\\u9ed1\\u767d\",\"!=\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"]},\"is-rid-grid\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u9664\\u7f51\\u7eb9\",\"desc\":\"\\u53bb\\u9664\\u56fe\\u50cf\\u4e2d\\u7684\\u7f51\\u7eb9\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"is-multiout!=true\",\"mode!=\\u9ed1\\u767d\",\"!=\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"]},\"is-err-extension\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u9519\\u8bef\\u6269\\u6563\",\"desc\":\"\\u4ee5\\u70b9\\u9635\\u5f62\\u5f0f\\u6784\\u5efa\\u56fe\\u50cf\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_or\":[\"mode==\\u9ed1\\u767d\"]},\"is-noise-optimize\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u9ed1\\u767d\\u56fe\\u50cf\\u566a\\u70b9\\u4f18\\u5316\",\"desc\":\"\\u53bb\\u9664\\u56fe\\u50cf\\u4e2d\\u7684\\u5b64\\u7acb\\u9ed1\\u70b9\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_or\":[\"mode==\\u9ed1\\u767d\"]},\"noise-size\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u566a\\u70b9\\u4f18\\u5316\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u9700\\u8981\\u53bb\\u9664\\u7684\\u9ed1\\u8272\\u5b64\\u7acb\\u70b9\\u7684\\u8fde\\u901a\\u4e2a\\u6570\",\"type\":\"int\",\"cur\":30,\"default\":30,\"size\":4,\"range\":{\"min\":10,\"max\":50,\"step\":1},\"depend_or\":[\"is-noise-optimize==true\"]},\"blank-sensitivity\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u8df3\\u8fc7\\u7a7a\\u767d\\u9875\\u7075\\u654f\\u5ea6\",\"desc\":\"\\u6570\\u503c\\u8d8a\\u5927��\\u5219\\u8d8a\\u5bb9\\u6613\\u8df3\\u8fc7\",\"type\":\"int\",\"cur\":50,\"default\":50,\"size\":4,\"range\":{\"min\":1,\"max\":100,\"step\":1},\"depend_or\":[\"page==\\u8df3\\u8fc7\\u7a7a\\u767d\\u9875��\\u901a\\u7528��\",\"==\\u8df3\\u8fc7\\u7a7a\\u767d\\u9875��\\u53d1\\u7968\\u7eb8��\"]},\"fold-type\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u5bf9\\u6298\\u6a21\\u5f0f\",\"desc\":\"\",\"type\":\"string\",\"cur\":\"\\u5de6\\u53f3\\u5bf9\\u6298\",\"default\":\"\\u5de6\\u53f3\\u5bf9\\u6298\",\"size\":50,\"range\":[\"\\u5de6\\u53f3\\u5bf9\\u6298\",\"\\u4e0a\\u4e0b\\u5bf9\\u6298\",\"\\u81ea\\u52a8\\u5bf9\\u6298\"],\"depend_or\":[\"page==\\u5bf9\\u6298\"]},\"is-exchange\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u4ea4\\u6362\\u6b63\\u53cd\\u9762\",\"desc\":\"\\u4ea4\\u6362\\u6bcf\\u5f20\\u6587\\u7a3f\\u7684\\u6b63\\u53cd\\u9762\\u51fa\\u56fe\\u987a\\u5e8f\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"page!=\\u5355\\u9762\"]},\"is-custom-gamma\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"light\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u542f\\u7528\\u8272\\u8c03\\u66f2\\u7ebf\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u56fe\\u50cf\\u8272\\u8c03\\u6548\\u679c\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},"); -//static std::string img_opt2("\"brightness\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"light\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u4eae\\u5ea6\\u503c\",\"desc\":\"\\u8c03\\u6574\\u56fe\\u50cf\\u4eae\\u5ea6\",\"type\":\"int\",\"cur\":128,\"default\":128,\"size\":4,\"range\":{\"min\":1,\"max\":255,\"step\":1},\"depend_and\":[\"is-custom-gamma==false\"]},\"contrast\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"light\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u5bf9\\u6bd4\\u5ea6\",\"desc\":\"\\u8c03\\u6574\\u56fe\\u50cf\\u5bf9\\u6bd4\\u5ea6\",\"type\":\"int\",\"cur\":4,\"default\":4,\"size\":4,\"range\":{\"min\":1,\"max\":7,\"step\":1},\"depend_and\":[\"is-custom-gamma==false\"]},\"gamma\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"light\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u4f3d\\u9a6c\\u503c\",\"desc\":\"\\u8c03\\u6574\\u56fe\\u50cf\\u4f3d\\u739b\\u503c\",\"type\":\"float\",\"cur\":1.000000,\"default\":1.000000,\"size\":4,\"range\":{\"min\":0.010000,\"max\":5.000000,\"step\":0.499000},\"depend_and\":[\"is-custom-gamma==false\"]},\"color-correction\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8272\\u504f\\u6821\\u6b63\",\"desc\":\"\\u8272\\u5f69\\u8fd8\\u539f\\u5ea6\\u77eb\\u6b63\\u529f\\u80fd\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"is-anti-skew\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u81ea\\u52a8\\u7ea0\\u504f\",\"desc\":\"\\u81ea\\u52a8\\u7ea0\\u6b63\\u6b6a\\u659c\\u9001\\u5165\\u7684\\u6587\\u7a3f\\u56fe\\u50cf\",\"type\":\"bool\",\"cur\":true,\"default\":true,\"size\":4,\"depend_or\":[\"page!=\\u5bf9\\u6298\"]},\"is-split\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u56fe\\u50cf\\u62c6\\u5206\",\"desc\":\"\\u81ea\\u52a8\\u62c6\\u5206\\u56fe\\u50cf\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"page!=\\u5bf9\\u6298\",\"!=\\u8df3\\u8fc7\\u7a7a\\u767d\\u9875��\\u53d1\\u7968\\u7eb8��\",\"!=\\u8df3\\u8fc7\\u7a7a\\u767d\\u9875��\\u901a\\u7528��\"]},\"is-erase-black-frame\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u6d88\\u9664\\u9ed1\\u6846\",\"desc\":\"\\u6d88\\u9664\\u6587\\u7a3f\\u8303\\u56f4\\u5916\\u7684\\u9ed1\\u8272\\u80cc\\u666f\",\"type\":\"bool\",\"cur\":true,\"default\":true,\"size\":4},\"bkg-fill-mode\":{\"category\":\"advanced\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u80cc\\u666f\\u586b\\u5145\\u65b9\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u80cc\\u666f\\u586b\\u5145\\u65b9\\u5f0f\",\"type\":\"string\",\"cur\":\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"default\":\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"size\":40,\"range\":[\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"\\u51f9\\u591a\\u8fb9\\u5f62\"],\"depend_or\":[\"is-erase-black-frame==true\"]},\"is-fill-color\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8272\\u5f69\\u586b\\u5145\",\"desc\":\"\\u542f\\u7528\\u540e\\u9ed1\\u6846\\u90e8\\u5206\\u5c06\\u586b\\u5145\\u4e3a\\u6587\\u7a3f\\u5e95\\u8272\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"is-erase-black-frame==true\"]},\"threshold\":{\"category\":\"advanced\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u9608\\u503c\",\"desc\":\"\\u6587\\u7a3f\\u5e95\\u8272\\u4e0e\\u9ed1\\u8272\\u80cc\\u666f\\u7070\\u5ea6\\u503c\\u7684\\u5dee\\u503c\\u5927\\u4e8e\\u8be5\\u503c��\\u624d\\u4f1a\\u88ab\\u8bc6\\u522b\\u4e3a\\u6587\\u7a3f\",\"type\":\"int\",\"cur\":40,\"default\":40,\"size\":4,\"range\":{\"min\":30,\"max\":50,\"step\":1},\"depend_or\":[\"is-erase-black-frame==true\",\"paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\",\"==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\",\"is-anti-skew==true\"]},\"anti-noise-level\":{\"category\":\"advanced\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u80cc\\u666f\\u6297\\u566a\\u7b49\\u7ea7\",\"desc\":\"\\u80fd\\u591f\\u5bb9\\u5fcd\\u7684\\u80cc\\u666f\\u6742\\u8272\\u6761\\u7eb9\\u7684\\u5bbd\\u5ea6\",\"type\":\"int\",\"cur\":8,\"default\":8,\"size\":4,\"range\":{\"min\":1,\"max\":20,\"step\":1},\"depend_or\":[\"is-erase-black-frame==true\",\"paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\",\"==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\",\"is-anti-skew==true\"]},\"margin\":{\"category\":\"advanced\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8fb9\\u7f18\\u7f29\\u8fdb\",\"desc\":\"\\u5bfb\\u627e\\u6587\\u7a3f\\u8fb9\\u7f18\\u65f6\\u5bf9\\u8fb9\\u7f18\\u7684\\u4fb5\\u5165\\u7a0b\\u5ea6\",\"type\":\"int\",\"cur\":5,\"default\":5,\"size\":4,\"range\":{\"min\":5,\"max\":30,\"step\":1},\"depend_or\":[\"is-erase-black-frame==true\",\"paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\",\"==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\",\"is-anti-skew==true\"]},\"is-dark-sample\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u6df1\\u8272\\u6837\\u5f20\",\"desc\":\"\\u542f\\u7528\\u8be5\\u6a21\\u5f0f\\u9632\\u6b62\\u6df1\\u8272\\u5e95\\u8272\\u7684\\u6587\\u7a3f\\u56fe\\u50cf\\u88ab\\u8bef\\u5904\\u7406\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"page!=\\u5bf9\\u6298\",\"is-erase-black-frame!=true\",\"paper!=\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\",\"!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\",\"is-anti-skew!=true\"]},\"is-anti-permeate\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u9632\\u6b62\\u6e17\\u900f\",\"desc\":\"\\u9632\\u6b62\\u80cc\\u9762\\u56fe\\u6848\\u6e17\\u900f\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"permeate-level\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u9632\\u6b62\\u6e17\\u900f\\u7b49\\u7ea7\",\"desc\":\"\\u9009\\u62e9\\u9632\\u6b62\\u6e17\\u900f\\u7684\\u7b49\\u7ea7\",\"type\":\"string\",\"cur\":\"\\u8f83\\u5f31\",\"default\":\"\\u8f83\\u5f31\",\"size\":16,\"range\":[\"\\u5f31\",\"\\u8f83\\u5f31\",\"\\u4e00\\u822c\",\"\\u8f83\\u5f3a\",\"\\u5f3a\"],\"depend_or\":[\"is-anti-permeate==true\"]},\"is-rid-hole-l\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664��\\u5de6\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u4e0a\\u7684\\u5de6\\u4fa7\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"search-hole-range-l\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u5de6\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"cur\":0.100000,\"default\":0.100000,\"size\":4,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend_and\":[\"is-rid-hole-l==true\"]},\"is-rid-hole-r\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664��\\u53f3\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u4e0a\\u7684\\u53f3\\u4fa7\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"search-hole-range-r\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u53f3\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"cur\":0.100000,\"default\":0.100000,\"size\":4,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend_and\":[\"is-rid-hole-r==true\"]},\"is-rid-hole-t\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664��\\u4e0a\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u7684\\u4e0a\\u90e8\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"search-hole-range-t\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u4e0a\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"cur\":0.100000,\"default\":0.100000,\"size\":4,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend_and\":[\"is-rid-hole-t==true\"]},\"is-rid-hole-b\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664��\\u4e0b\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u7684\\u4e0b\\u90e8\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"search-hole-range-b\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"imgproc\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u4e0b\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"cur\":0.100000,\"default\":0.100000,\"size\":4,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend_and\":[\"is-rid-hole-b==true\"]},\"direction\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u6587\\u7a3f\\u65b9\\u5411\",\"desc\":\"\\u8bbe\\u7f6e\\u56fe\\u50cf\\u7684\\u65b9\\u5411\",\"type\":\"string\",\"cur\":\"0��\",\"default\":\"0��\",\"size\":40,\"range\":[\"0��\",\"90��\",\"180��\",\"-90��\",\"\\u81ea\\u52a8\\u6587\\u672c\\u65b9\\u5411\\u8bc6\\u522b��\"]},\"is-rotate-bkg-180\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u65cb\\u8f6c180��\",\"desc\":\"\\u80cc\\u9762\\u626b\\u63cf\\u7684\\u56fe\\u50cf\\u65cb\\u8f6c180��\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_and\":[\"page!=\\u5355\\u9762\",\"!=\\u5bf9\\u6298\",\"direction!=\\u81ea\\u52a8\\u6587\\u672c\\u65b9\\u5411\\u8bc6\\u522b��\"]}}"); -// -//static std::string hardware_opt("{\"paper\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u7eb8\\u5f20\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u51fa\\u56fe\\u5927\\u5c0f\",\"type\":\"string\",\"cur\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"default\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"size\":48,\"range\":[\"A3\",\"8\\u5f00\",\"A4\",\"A4\\u6a2a\\u5411\",\"16\\u5f00\",\"16\\u5f00\\u6a2a\\u5411\",\"A5\",\"A5\\u6a2a\\u5411\",\"A6\",\"A6\\u6a2a\\u5411\",\"B4\",\"B5\",\"B5\\u6a2a\\u5411\",\"B6\",\"B6\\u6a2a\\u5411\",\"Letter\",\"Letter\\u6a2a\\u5411\",\"Double Letter\",\"LEGAL\",\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\",\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\",\"\\u4e09\\u8054\\u8bd5\\u5377\"]},\"is-size-check\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u5c3a\\u5bf8\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u7eb8\\u5f20\\u5b9e\\u9645\\u5c3a\\u5bf8\\u4e0e\\u8bbe\\u7f6e\\u662f\\u5426\\u5339\\u914d\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_or\":[\"paper==A3\",\"==A4\",\"==A4\\u6a2a\\u5411\",\"==A5\",\"==A5\\u6a2a\\u5411\",\"==A6\",\"==A6\\u6a2a\\u5411\",\"==B4\",\"==B5\",\"==B5\\u6a2a\\u5411\",\"==B6\",\"==B6\\u6a2a\\u5411\",\"==Double Letter\",\"==LEGAL\",\"==Letter\",\"==Letter\\u6a2a\\u5411\"]},\"resolution\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"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\":{\"min\":100,\"max\":600,\"step\":1}},\"image-quality\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u753b\\u8d28\",\"desc\":\"\\u9009\\u62e9\\u626b\\u63cf\\u4eea\\u7684\\u753b\\u8d28\\u6a21\\u5f0f\",\"type\":\"string\",\"cur\":\"\\u901f\\u5ea6\\u4f18\\u5148\",\"default\":\"\\u901f\\u5ea6\\u4f18\\u5148\",\"size\":24,\"range\":[\"\\u901f\\u5ea6\\u4f18\\u5148\",\"\\u753b\\u8d28\\u4f18\\u5148\"],\"depend_or\":[\"resolution>=300\"]},\"is-wait-scan\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\",\"desc\":\"\\u542f\\u7528\\u540e��\\u6587\\u7a3f\\u653e\\u5165\\u626b\\u63cf\\u4eea\\u65f6\\u5c06\\u81ea\\u52a8\\u542f\\u52a8\\u626b\\u63cf\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"scan-mode\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u9009\\u62e9\\u6307\\u5b9a\\u6570\\u91cf\\u626b\\u63cf\\u6216\\u8fde\\u7eed\\u626b\\u63cf\",\"type\":\"string\",\"cur\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"default\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"size\":32,\"range\":[\"\\u8fde\\u7eed\\u626b\\u63cf\",\"\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"],\"depend_or\":[\"is-wait-scan==false\"]},\"scan-count\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u626b\\u63cf\\u6570\\u91cf\",\"desc\":\"\\u626b\\u63cf\\u6307\\u5b9a\\u6570\\u91cf\",\"type\":\"int\",\"cur\":1,\"default\":1,\"size\":4,\"depend_or\":[\"scan-mode==\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"]},\"is-ultrosonic\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8d85\\u58f0\\u6ce2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u51fa\\u73b0\\u53cc\\u5f20\\u9001\\u5165\",\"type\":\"bool\",\"cur\":true,\"default\":true,\"size\":4},\"double-feed\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u53cc\\u5f20\\u56fe\\u7247\\u5904\\u7406\",\"desc\":\"\\u68c0\\u6d4b\\u5230\\u53cc\\u5f20\\u8fdb\\u7eb8\\u540e\\u7684\\u5904\\u7406\\u65b9\\u5f0f\",\"type\":\"string\",\"cur\":\"\\u4e22\\u5f03\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\",\"default\":\"\\u4e22\\u5f03\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\",\"size\":40,\"range\":[\"\\u4e22\\u5f03\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\",\"\\u4e0a\\u4f20\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\"],\"depend_or\":[\"is-ultrosonic==true\"]},\"is-staple\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u88c5\\u8ba2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u51fa\\u73b0\\u7c98\\u8fde\\u9001\\u5165\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"is-check-askew\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u6b6a\\u659c\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u51fa\\u73b0\\u6b6a\\u659c\\u9001\\u5165\",\"type\":\"bool\",\"cur\":true,\"default\":true,\"size\":4},\"askew-range\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u6b6a\\u659c\\u5bb9\\u5fcd\\u5ea6\",\"desc\":\"\\u503c\\u8d8a\\u5c0f��\\u80fd\\u5bb9\\u5fcd\\u5f97\\u9001\\u5165\\u6587\\u7a3f\\u6b6a\\u659c\\u89d2\\u5ea6\\u8d8a\\u5c0f\",\"type\":\"int\",\"cur\":3,\"default\":3,\"size\":4,\"range\":{\"min\":1,\"max\":5,\"step\":1},\"depend_or\":[\"is-check-askew==true\"]},\"is-check-dog-ear\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u6298\\u89d2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u6587\\u7a3f\\u662f\\u5426\\u5b58\\u5728\\u6298\\u89d2\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"dog-ear-size\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u6298\\u89d2\\u5927\\u5c0f\",\"desc\":\"\\u503c\\u8d8a\\u5c0f��\\u80fd\\u68c0\\u6d4b\\u5230\\u7684\\u6298\\u89d2\\u8d8a\\u5c0f\",\"type\":\"int\",\"cur\":70,\"default\":70,\"size\":4,\"range\":{\"min\":0,\"max\":100,\"step\":1},\"depend_or\":[\"is-check-dog-ear==true\"]},\"feed-strength\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"string\",\"cur\":\"\\u5f31\",\"default\":\"\\u5f31\",\"size\":16,\"range\":[\"\\u5f31\",\"\\u4e00\\u822c\",\"\\u5f3a\"]},\"time-to-sleep\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u4f11\\u7720\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u4f11\\u7720\\u65f6\\u95f4\",\"type\":\"string\",\"cur\":\"\\u4e0d\\u4f11\\u7720\",\"default\":\"\\u4e0d\\u4f11\\u7720\",\"size\":24,\"range\":[\"\\u4e0d\\u4f11\\u7720\",\"\\u4e94\\u5206\\u949f\",\"\\u5341\\u5206\\u949f\",\"\\u534a\\u5c0f\\u65f6\",\"\\u4e00\\u5c0f\\u65f6\",\"\\u4e24\\u5c0f\\u65f6\",\"\\u56db\\u5c0f\\u65f6\"]},\"is-auto-strength\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u81ea\\u52a8\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u626b\\u63cf\\u4eea\\u81ea\\u52a8\\u4fee\\u6b63\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"feed-strength-value\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"feeder\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\" \\u8fdb\\u7eb8\\u5931\\u8d25\\u7387\",\"desc\":\"\\u9ad8\\u4e8e\\u8be5\\u503c\\u65f6\\u626b\\u63cf\\u4eea\\u5c06\\u8c03\\u6574\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"float\",\"cur\":0.100000,\"default\":0.100000,\"size\":4,\"range\":{\"min\":0.100000,\"max\":0.900000,\"step\":0.080000},\"depend_or\":[\"is-auto-strength==true\"]}}"); - -class readonly_cfg : public sane_cfg_provider -{ - json* jsn_; - - std::string get_ip(void) - { - std::string val(sys_util::get_command_output("ifconfig | grep broadcast")); - char buf[40] = { 0 }; - - if (sscanf(val.c_str(), " inet %s", buf)) - val = buf; - - return std::move(val); - } - std::string get_mac(void) - { - std::string val(sys_util::get_command_output("ifconfig | grep ether")); - char buf[40] = { 0 }; - - if (sscanf(val.c_str(), " ether %s", buf)) - val = buf; - - return std::move(val); - } - -public: - readonly_cfg() : jsn_(nullptr) - { - jsn_ = new json(); - jsn_->attach_text((char*)"{\"dev-sn\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"\\u8BBE\\u5907\\u5C5E\\u6027\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8bbe\\u5907\\u5e8f\\u5217\\u53f7\",\"desc\":\"\\u8bbe\\u5907\\u552f\\u4e00\\u7f16\\u7801\",\"type\":\"string\",\"cur\":\"G100S20230001\",\"size\":20,\"ver\":1},\"fmw-ver\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"\\u8BBE\\u5907\\u5C5E\\u6027\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u56fa\\u4ef6\\u7248\\u672c\\u53f7\",\"desc\":\"\\u8bbe\\u5907\\u9a71\\u52a8\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"cur\":\"FMWV1001\",\"size\":10,\"ver\":1},\"ip-addr\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"\\u8BBE\\u5907\\u5C5E\\u6027\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8bbe\\u5907IP\\u5730\\u5740\",\"desc\":\"\\u5f53\\u8bbe\\u5907\\u8fde\\u63a5\\u7f51\\u7edc\\u65f6\\u5206\\u914d\\u7684IP\\u5730\\u5740\",\"type\":\"string\",\"cur\":\"0.0.0.0\",\"size\":60,\"ver\":1},\"mac-addr\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"\\u8BBE\\u5907\\u5C5E\\u6027\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u8bbe\\u5907MAC\\u5730\\u5740\",\"desc\":\"\\u8bbe\\u5907MAC\\u5730\\u5740\",\"type\":\"string\",\"cur\":\"00:11:22:33:44:55\",\"size\":30,\"ver\":1}}"); - } - - -protected: - ~readonly_cfg() - { - jsn_->release(); - } - -public: - virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) override - { - if (!len) - return EINVAL; - - std::string val(""), str(""); - - if (cfg_name) - { - if (strcmp(cfg_name, "ip-addr") == 0) - str = val = get_ip(); - else if (strcmp(cfg_name, "mac-addr") == 0) - str = val = get_mac(); - else - { - json* child = nullptr; - if (jsn_->get_value(cfg_name, child) && child) - { - val = sane_cfg_provider::sane_option_value_get(child, "cur", &str); - - child->release(); - } - } - } - else - { - std::string cur(get_ip()); - if (!cur.empty()) - { - json* child = nullptr; - if (jsn_->get_value("ip-addr", child) && child) - { - child->set_value("cur", cur.c_str()); - child->release(); - } - } - - cur = get_mac(); - if (!cur.empty()) - { - json* child = nullptr; - if (jsn_->get_value("mac-addr", child) && child) - { - child->set_value("cur", cur.c_str()); - child->release(); - } - } - - val = jsn_->to_string(); - log_cls::log(LOG_LEVEL_ALL, "readonly config json: %s\n", val.c_str()); - } - - if (val.empty()) - return ENOENT; - - if(strval) - *strval = std::move(str); - - if (*len < val.length()) - { - *len = val.length() + 4; - return ENOMEM; - } - else - { - memcpy(buf, val.c_str(), val.length()); - *len = val.length(); - - return 0; - } - } - virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override - { - // read-only attributes not support this operation !!! - return EINVAL; - } -}; - -class image_packet : public data_source -{ - MemoryPtr img_; - dyn_mem_ptr head_; - uint32_t offset_; - uint32_t ind_; - uint64_t cur_mem_; - -public: - image_packet(MemoryPtr img, uint32_t cnt, uint32_t scanid, uint64_t total_mem) : img_(img), offset_(0), ind_(cnt), cur_mem_(total_mem) - { - LPPACK_BASE pack = nullptr; - LPPACKIMAGE pimg = nullptr; - - head_ = dyn_mem::memory(sizeof(PACK_BASE) + sizeof(PACKIMAGE)); - pack = (LPPACK_BASE)head_->ptr(); - pimg = (LPPACKIMAGE)pack->payload; - BASE_PACKET_REPLY(*pack, PACK_CMD_SCAN_IMG_ROGER, scanid, 0); - pack->payload_len = sizeof(PACKIMAGE); - - pimg->pos.new_img = 1; - pimg->pos.img_over = 1; - pimg->pos.paper_ind = cnt; - pimg->data_size = img->size(); - pimg->info_size = 0; - - head_->set_len(sizeof(PACK_BASE) + sizeof(PACKIMAGE)); - log_cls::log(LOG_LEVEL_ALL, "Image-%04u wait to be sent: size = %u, memory usage %s\n", ind_, img->size(), sys_util::format_readable_bytes(cur_mem_).c_str()); - } - -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()); - } - -public: - virtual bool is_memory_block(void) override - { - return false; - } - virtual uint32_t get_rest(void) override - { - return head_->get_rest() + img_->size() - offset_; - } - - // following API valid when is_memory_block() return true - virtual uint8_t* ptr(void) override - { - return nullptr; - } - - // following API valid when is_memory_block() return false. return error code - virtual int fetch_data(void* buf, uint32_t* size) override - { - if(head_->get_rest()) - { - if(*size < head_->get_rest()) - { - memcpy(buf, head_->ptr(), *size); - } - else - { - memcpy(buf, head_->ptr(), head_->get_rest()); - *size = head_->get_rest(); - } - head_->used(*size); - } - else - { - if(*size + offset_ >= img_->size()) - { - memcpy(buf, img_->data() + offset_, img_->size() - offset_); - *size = img_->size() - offset_; - offset_ = img_->size(); - } - else - { - memcpy(buf, img_->data() + offset_, *size); - offset_ += *size; - } - } - - return 0; - } -}; - -void dump_buf(uint8_t *data, int len) -{ - uint32_t addr = 0; - std::string cont(""), asc(""); - char buf[20] = { 0 }; - for(int i = 0; i < len; ++i) - { - if((i % 16) == 0) - { - if (cont.length()) - log_cls::log(LOG_LEVEL_ALL, "%s %s\n", cont.c_str(), asc.c_str()); - sprintf(buf, "0x%08x ", addr); - addr += 16; - cont = buf; - asc = ""; - } - else if((i % 8) == 0) - { - cont += " "; - } - - uint8_t v = data[i]; - sprintf(buf, "%02X ", v); - cont += buf; - if(v >= 0x20 && v < 0x7f) - asc.append(1, v); - else - asc += "."; - } - if(asc.length()) - { - std::string pad(" "); - if(asc.length() <= 8) - pad.erase((16 - asc.length()) * 3 + 2); - else if(asc.length() < 16) - pad.erase((16 - asc.length()) * 3); - else - pad = ""; - log_cls::log(LOG_LEVEL_ALL, "%s%s %s\n", cont.c_str(), pad.c_str(), asc.c_str()); - } -} -std::string load_mini_file(const char* path) -{ - FILE* src = fopen(path, "rb"); - std::string cont(""); - - if(src) - { - int len = 0; - - fseek(src, 0, SEEK_END); - len = ftell(src); - cont.resize(len); - fseek(src, 0, SEEK_SET); - fread(&cont[0], 1, len, src); - fclose(src); - } - - return cont; -} - -dyn_mem_ptr UsbDevice::unhandled_ep0(struct usb_functionfs_event* pev) -{ - return nullptr; -} -dyn_mem_ptr UsbDevice::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) -{ - dyn_mem_ptr reply = nullptr; - LPPACK_BASE pk = nullptr; - size_t base_head_size = sizeof(PACK_BASE); - - if(pack->size != base_head_size) - { - log_cls::log(LOG_LEVEL_ALL, "Unknown Packet with %d bytes:\n", *used); - dump_buf((uint8_t*)pack, *used); - reply = dyn_mem::memory(base_head_size); - LPPACK_BASE p = (LPPACK_BASE)reply->ptr(); - BASE_PACKET_REPLY(*p, PACK_CMD_INVALID, pack->pack_id, pack->cmd); - reply->set_len(base_head_size); - - return reply; - } - - switch(pack->cmd) - { - case PACK_CMD_SYNC: - *used = sizeof(PACK_BASE); - reply = dyn_mem::memory(base_head_size); - pk = (LPPACK_BASE)reply->ptr(); - BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, 0); - reply->set_len(base_head_size); - break; - case PACK_CMD_SETTING_GET_CUR: - if(*used < base_head_size + pack->payload_len) - *used = 0; - else - { - std::string val(""), str(""); - uint32_t err = cfg_->get_config(val, pack->payload, &str); - LPCFGVAL cfg = nullptr; - - if (val.empty()) - val = "No value found."; - log_cls::log(LOG_LEVEL_ALL, "Option '%s' value: %s\n", pack->payload, str.c_str()); - reply = dyn_mem::memory(base_head_size + sizeof(CFGVAL) + strlen(pack->payload) + 1 + val.length() + 1); - pk = (LPPACK_BASE)reply->ptr(); - BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, err); - cfg = (LPCFGVAL)pk->payload; - cfg->val_size = val.length(); - cfg->val_off = 0; - cfg->name_off = val.length() + 1; - pk->payload_len = sizeof(CFGVAL) + strlen(pack->payload) + 1 + val.length() + 1; - 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; - } - break; - case PACK_CMD_SETTING_GET: - *used = base_head_size; - { - std::string val(""); - uint32_t err = cfg_->get_config(val); - - reply = dyn_mem::memory(base_head_size + val.length() + 1); - pk = (LPPACK_BASE)reply->ptr(); - BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, err); - strcpy(pk->payload, val.c_str()); - pk->payload_len = val.length() + 1; - reply->set_len(base_head_size + val.length() + 1); - } - break; - case PACK_CMD_SETTING_SET: - if (*used < base_head_size + pack->payload_len) - *used = 0; - else - { - LPCFGVAL cfg = (LPCFGVAL)pack->payload, - cfg_ret = nullptr; - std::string name(cfg->data + cfg->name_off); - size_t l = base_head_size + sizeof(CFGVAL) + name.length() + 1 + cfg->max_size + 1, val_size = cfg->val_size; - int32_t err = 0; - uint32_t after = 0; - - reply = dyn_mem::memory(l); - pk = (LPPACK_BASE)reply->ptr(); - cfg_ret = (LPCFGVAL)pk->payload; - cfg_ret->name_off = 0; - strcpy(cfg_ret->data + cfg_ret->name_off, name.c_str()); - cfg_ret->val_off = name.length() + 1; - memcpy(cfg_ret->data + cfg_ret->val_off, cfg->data + cfg->val_off, cfg->val_size); - cfg_ret->val_size = cfg->val_size; - cfg_ret->max_size = cfg->max_size; - cfg_ret->type = cfg->type; - err = cfg_->set_config(cfg->data + cfg->name_off, cfg_ret->data + cfg_ret->val_off, &val_size, &after); - cfg_ret->after_do = after; - cfg_ret->val_size = val_size; - BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, err); - pk->payload_len = sizeof(CFGVAL) + name.length() + 1 + cfg->max_size + 1; - reply->set_len(l); - } - break; - case PACK_CMD_FILE_WRITE_REQ: - if(*used < pack->payload_len + pack->size) - { - *used = 0; - } - else - { - LPTXFILE pfi = (LPTXFILE)pack->payload; - std::string path(pfi->path); - int err = 0; - file_saver *saver = new file_saver(); - - err = saver->open(path.c_str(), pfi->size); - reply = dyn_mem::memory(base_head_size); - reply->set_len(base_head_size); - BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err); - *used = base_head_size + pack->payload_len; - if(err) - { - saver->release(); - saver = nullptr; - } - else - { - saver->set_packet_param(pack->cmd, pack->pack_id); - } - log_cls::log(LOG_LEVEL_DEBUG, "receive file (%u bytes): %s = %d\n", pfi->size, path.c_str(), err); - *required = dynamic_cast(saver); - } - break; - case PACK_CMD_FILE_READ_REQ: - if(*used < pack->payload_len + pack->size) - { - *used = 0; - } - else - { - LPTXFILE pfi = (LPTXFILE)pack->payload; - std::string path(pfi->path); - int err = 0; - file_reader *reader = new file_reader(); - - err = reader->open(path.c_str()); - reply = dyn_mem::memory(base_head_size + sizeof(TXFILE)); - reply->set_len(base_head_size + sizeof(TXFILE)); - BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err); - *used = base_head_size + pack->payload_len; - log_cls::log(LOG_LEVEL_DEBUG, "To send file '%s' with %u bytes = %d\n", path.c_str(), reader->get_rest(), err); - if(err) - { - reader->release(); - reader = nullptr; - } - else - { - ((LPPACK_BASE)reply->ptr())->payload_len = sizeof(TXFILE); - ((LPTXFILE)((LPPACK_BASE)reply->ptr())->payload)->size = reader->get_rest(); - reader->set_packet_param(pack->cmd, pack->pack_id); - } - *required = dynamic_cast(reader); - } - break; - case PACK_CMD_SCAN_START: - { - int err = 0; - img_cnt_ = 0; - scan_id_ = pack->pack_id; - scan_err_ = 0; - if(scan_over_pack_) - { - scan_over_pack_->release(); - scan_over_pack_ = nullptr; - } - - { - ctrl_handler(-1, (usb_ctrlrequest*)SR_IM_CLEAR, (unsigned char*)0); - log_cls::log(LOG_LEVEL_ALL, "Memory usage before starting to scan: %s\n", sys_util::format_readable_bytes(sys_util::get_memory_usage("scan")).c_str()); - bool ret = ctrl_handler(-1, (usb_ctrlrequest*)15, (unsigned char*)0x160); // hardware configuration - - ctrl_handler(-1, (usb_ctrlrequest*)SR_SCAN_CNT, (unsigned char*)scan_cnt_); - ctrl_handler(-1, (usb_ctrlrequest*)SR_SCAN_DPI, (unsigned char*)dpi_); - ctrl_handler(-1, (usb_ctrlrequest*)SR_CONFIF_IMGPROCPARAM, (unsigned char*)0); - log_cls::log(LOG_LEVEL_ALL, "Start scanning %d papers and %d DPI ...\n", scan_cnt_, dpi_); - ret = ctrl_handler(-1, nullptr, nullptr); - log_cls::log(LOG_LEVEL_ALL, "Start scanning %s\n", ret ? "OK" : "Failed"); - log_cls::log(LOG_LEVEL_ALL, "Memory usage after scanning started: %s\n", sys_util::format_readable_bytes(sys_util::get_memory_usage("scan")).c_str()); - } - - reply = dyn_mem::memory(base_head_size); - reply->set_len(base_head_size); - BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err); - *used = base_head_size; - } - break; - case PACK_CMD_SCAN_STOP: - { - int err = 0; - - log_cls::log(LOG_LEVEL_ALL, "Received command Stop-Scan.\n"); - ctrl_handler(-1, nullptr, (unsigned char*)1); - reply = dyn_mem::memory(base_head_size); - reply->set_len(base_head_size); - BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err); - *used = base_head_size; - } - break; - default: - log_cls::log(LOG_LEVEL_ALL, "Unhandled Packet with command %d:\n", pack->cmd); - dump_buf((uint8_t*)pack, *used); - reply = dyn_mem::memory(base_head_size); - LPPACK_BASE p = (LPPACK_BASE)reply->ptr(); - BASE_PACKET_REPLY(*p, pack->cmd + 1, pack->pack_id, EINVAL); - reply->set_len(base_head_size); - break; - } - - return reply; -} void UsbDevice::do_system_command(const char* cmd) { log_cls::log(LOG_LEVEL_ALL, "invoking system command: %s ...\n", cmd); get_system_output(cmd); log_cls::log(LOG_LEVEL_ALL, "invoked system command: %s.\n", cmd); } -void UsbDevice::init(void) + +#include "commondef.h" +int UsbDevice::start_scan(void) { - readonly_cfg* r = new readonly_cfg(); - hardware *hrd = new hardware(); + ctrl_handler(-1, (usb_ctrlrequest*)SR_IM_CLEAR, (unsigned char*)0); + ctrl_handler(-1, (usb_ctrlrequest*)SR_CONFIF_IMGPROCPARAM, (unsigned char*)0); - 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]}}"; - l = get_config(&dpi_, &l, "resolution"); - l = sizeof(scan_cnt_); - l = get_config(&scan_cnt_, &l, "count"); - 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(); + return ctrl_handler(-1, nullptr, nullptr) ? 0 : EBADF; } -void UsbDevice::save_image(MemoryPtr data, bool img) +int UsbDevice::stop_scan(void) { - static uint64_t max_mem = 0; + return ctrl_handler(-1, nullptr, (unsigned char*)1) ? 0 : EBADF; +} +int UsbDevice::set_dpi(int *dpix, int* dpiy) +{ + int dpi = 0; - if(img) + if(dpix) { - uint64_t n = sys_util::get_memory_usage("scan"); - uint32_t que = 0; - image_packet *ip = new image_packet(data, ++img_cnt_, scan_id_, n); - - if(max_mem < n) - max_mem = n; - - que = usb_->write_bulk(ip); - ip->release(); - - // check has completed ? - if(scan_over_pack_) - { - ctrl_handler(-2, (usb_ctrlrequest*)SR_GET_IMAGEPROCESSDONE, (unsigned char*)&n); - if(n) - { - usb_->write_bulk(scan_over_pack_); - scan_over_pack_->release(); - scan_over_pack_ = nullptr; - } - } - } - else if(data) - { - HGIntInfo* info = (HGIntInfo*)data->data(); - dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE)); - int cmd = /*PACK_CMD_SCAN_FINISHED_ROGER*/0, - err = 0; - - if(info->From != HGType::MBEvent || scan_id_ == 0) - log_cls::log(LOG_LEVEL_ALL, "Scanner event: From = %d, Code = %d, Img_Index = %d\n", info->From, info->Code, info->Img_Index); - - if(info->From == HGType::MtBoard) - { - cmd = PACK_CMD_SCAN_FINISHED_ROGER; - switch(info->Code) - { - case 2: - err = SCANNER_STATUS_NO_PAPER; - break; - case 4: - err = SCANNER_STATUS_COVER_OPENNED; - break; - case 8: - err = SCANNER_STATUS_FEED_FAILED; - break; - case 0x10: - err = SCANNER_STATUS_PAPER_JAMMED; - break; - case 0x20: - err = SCANNER_STATUS_DOUBLE_FEEDED; - break; - case 0x40: - err = SCANNER_STATUS_STAPLE_ON; - break; - case 0x80: - err = SCANNER_STATUS_PAPER_ASKEW; - break; - case 0x20000: - break; - } - } - else if(info->From == HGType::IMG) - { - if(info->Code == 1) - { - err = SCANNER_STATUS_DOGEAR; - cmd = PACK_CMD_SCAN_FINISHED_ROGER; - } - else if(info->Code == 2) - { - err = SCANNER_STATUS_SIZE_ERR; - cmd = PACK_CMD_SCAN_FINISHED_ROGER; - } - } - else if(info->From == HGType::V4L2 || info->From == HGType::STOPSCAN) - { - cmd = PACK_CMD_SCAN_FINISHED_ROGER; - } - - if(scan_id_ == 0 && info->From == HGType::MBEvent) - { - BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_STATUS_ROGER, 0, info->Code); - reply->set_len(sizeof(PACK_BASE)); - usb_->write_bulk(reply); - } + if(*dpix < 300) + *dpix = 200; + else if(*dpix < 500) + *dpix = 300; else - { - if(err && scan_err_ == 0) - scan_err_ = err; - if(scan_id_ && /*cmd == PACK_CMD_SCAN_FINISHED_ROGER*/info->From == HGType::STOPSCAN && scan_over_pack_ == nullptr) - { - char ebuf[20] = {0}; - - err = scan_err_; - log_cls::log(LOG_LEVEL_ALL, "Scan over with error: %s; Max memory usage: %s\n", log_cls::str_scanner_status((scanner_status)scan_err_, ebuf), sys_util::format_readable_bytes(max_mem).c_str()); - max_mem = 0; - BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), cmd, scan_id_, err); - reply->set_len(sizeof(PACK_BASE)); - scan_id_ = 0; - - // check if the image-proc-queue has completed ... - // ctrl_handler(-2, (usb_ctrlrequest*)SR_GET_IMAGEPROCESSDONE, (unsigned char*)&err); - err = 1; - if(err) - usb_->write_bulk(reply); - else - { - scan_over_pack_ = reply; - scan_over_pack_->add_ref(); - } - } - } - reply->release(); + *dpix = 600; + dpi = *dpix; } - else + if(dpiy) { - // 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) -{ - int32_t ret = EINVAL; - - if(!len) - return ret; - - if(cfg_name) - { - json *jsn = new json(); - if(jsn->attach_text(&cfg_text_[0])) - { - 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(); - - // if(*len < val.length()) - // { - // *len = val.length(); - // ret = ENOMEM; - // } - // else - // { - // memcpy(buf, val.c_str(), val.length()); - // *len = val.length(); - // } - // } - jsn->release(); - } - } - else - { - if(*len < cfg_text_.length() + 1) - { - *len = cfg_text_.length() + 4; - ret = ENOMEM; - } + if(*dpiy < 300) + *dpiy = 200; + else if(*dpiy < 500) + *dpiy = 300; else - { - strcpy((char*)buf, cfg_text_.c_str()); - *len = cfg_text_.length(); - ret = 0; - } - } + *dpiy = 600; - return ret; + if(dpi == 0) + dpi = *dpiy; + } + if(dpi == 0) + dpi = 200; + + return ctrl_handler(-1, (usb_ctrlrequest*)SR_SCAN_DPI, (unsigned char*)dpi) ? 0 : EBADF; } -int32_t UsbDevice::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +int UsbDevice::set_scan_num(int num) { - json *jsn = new json(); - int32_t ret = EINVAL; - - if(jsn->attach_text(&cfg_text_[0])) - { - json* child = nullptr; - - ret = ENOENT; - if(jsn->get_value(cfg_name, child) && child) - { - int val = 0; - child->get_value("affect", val); - if(afterdo) - *afterdo = val; - - if(strcmp(cfg_name, "resolution") == 0) - { - child->get_value("cur", val); - ret = EUCLEAN; - val = *(int*)data; - if(val == 100 || val == 150 || val == 200 || val == 300 || val == 600) - ret = 0; - else if(val < 125) - val = 100; - else if(val < 175) - val = 150; - else if(val < 250) - val = 200; - else if(val < 450) - val = 300; - else - val = 600; - *(int*)data = val; - child->set_value("cur", val); - dpi_ = val; - log_cls::log(LOG_LEVEL_ALL, "Set %s to %d\n", cfg_name, dpi_); - cfg_text_ = jsn->to_string(); - } - else if(strcmp(cfg_name, "count") == 0) - { - child->get_value("cur", val); - ret = EUCLEAN; - val = *(int*)data; - if(val == -1 || val == 1) - ret = 0; - else - val = -1; - *(int*)data = val; - child->set_value("cur", val); - scan_cnt_ = val; - log_cls::log(LOG_LEVEL_ALL, "Set %s to %d\n", cfg_name, scan_cnt_); - cfg_text_ = jsn->to_string(); - } - child->release(); - } - jsn->release(); - } - - return ret; + return ctrl_handler(-1, (usb_ctrlrequest*)SR_SCAN_CNT, (unsigned char*)num) ? 0 : EBADF; } +int UsbDevice::set_img_receiver(void* api, void* param) +{ + uint64_t cb[] = {(uint64_t)api, (uint64_t)param}; + return ctrl_handler(-1, (usb_ctrlrequest*)-1, (unsigned char*)cb) ? 0 : EBADF; +} #endif diff --git a/device/gxx-linux/usb/usbimageprocqueue.h b/device/gxx-linux/usb/usbimageprocqueue.h index 8f4d852..de22c50 100644 --- a/device/gxx-linux/usb/usbimageprocqueue.h +++ b/device/gxx-linux/usb/usbimageprocqueue.h @@ -9,19 +9,76 @@ #include +#include "./src/async_model/common/packet.h" + class UsbImageProcQueue { void(*img_keeper_)(MemoryPtr, bool, void*); void* kp_param_; + int scan_status_; + int dpi_x_; + int dpi_y_; + + int sensor_status_2_scanner_status(int ss) + { + switch(ss) + { + case 2: + ss = SCANNER_STATUS_NO_PAPER; + break; + case 4: + ss = SCANNER_STATUS_COVER_OPENNED; + break; + case 8: + ss = SCANNER_STATUS_FEED_FAILED; + break; + case 0x10: + ss = SCANNER_STATUS_PAPER_JAMMED; + break; + case 0x20: + ss = SCANNER_STATUS_DOUBLE_FEEDED; + break; + case 0x40: + ss = SCANNER_STATUS_STAPLE_ON; + break; + case 0x80: + ss = SCANNER_STATUS_PAPER_ASKEW; + break; + case 0x20000: + break; + } + + return ss; + } public: - UsbImageProcQueue(NotifyPtr notify) : img_keeper_(nullptr), kp_param_(nullptr) + UsbImageProcQueue(NotifyPtr notify) : img_keeper_(nullptr), kp_param_(nullptr), scan_status_(0), dpi_x_(200), dpi_y_(200) { this->notify = notify; } - void push(MemoryPtr image,bool containsimg) + void push(MemoryPtr image,bool containsimg) { + if(!containsimg) + { + void (*push_image)(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, void* param) = nullptr; + HGIntInfo* info = (HGIntInfo*)image->data(); + + *(uint64_t*)&push_image = (uint64_t)img_keeper_; + if(info->From == HGType::STOPSCAN) + { + if(push_image) + push_image(IMG_CB_STOPPED, nullptr, sensor_status_2_scanner_status(info->Code), 0, dpi_x_, dpi_y_, 0, PAPER_SIDE_LEFT, (clr_channel)0, (img_status)0, true, true, kp_param_); + } + else + { + scan_status_ = sensor_status_2_scanner_status(info->Code); + if(push_image) + push_image(IMG_CB_STATUS, nullptr, sensor_status_2_scanner_status(info->Code), 0, dpi_x_, dpi_y_, 0, PAPER_SIDE_LEFT, (clr_channel)0, (img_status)0, true, true, kp_param_); + } + } + return; + if(img_keeper_) img_keeper_(image, containsimg, kp_param_); else @@ -45,12 +102,36 @@ public: } + bool push_raw(void *data, int width, int height = 0, int type = 0, int scannnum = 0, unsigned int fpgaversion = 0, int status = 0) + { + if(scannnum == 1) + scan_status_ = 0; + + void (*push_image)(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, void* param) = nullptr; + + *(uint64_t*)&push_image = (uint64_t)img_keeper_; + if(push_image) + { + push_image(IMG_CB_IMAGE, data, width, height, dpi_x_, dpi_y_, scannnum, PAPER_SIDE_LEFT, (clr_channel)type, (img_status)status, true, true, kp_param_); + + return true; + } + + return false; + } void set_image_keeper(void(*img_keeper)(MemoryPtr, bool, void*), void* param) { + printf("UsbImageProcQueue::set_image_keeper(%p, %p)\n", img_keeper, param); + img_keeper_ = img_keeper; kp_param_ = param; } - + void set_dpi(int x, int y) + { + dpi_x_ = x; + dpi_y_ = y; + } + MemoryPtr front() { std::lock_guard lck(mx); diff --git a/device/gxx-linux/usb/usbnotify.cpp b/device/gxx-linux/usb/usbnotify.cpp index caf1095..58d0d14 100644 --- a/device/gxx-linux/usb/usbnotify.cpp +++ b/device/gxx-linux/usb/usbnotify.cpp @@ -48,7 +48,7 @@ void UsbNotify::run_notify() unsigned char buff[64]; while(brun) { - if (ae.wait(300000) && brun) + if (ae.wait(1000) && brun) { for(;;) { @@ -65,6 +65,7 @@ void UsbNotify::run_notify() usb->write_int(buff, sizeof(buff)); { + printf("\n notify msg "); std::lock_guard lck(mx); if(msgs.size()>0) msgs.pop(); diff --git a/device/gxx-linux/usb/usbreceive.cpp b/device/gxx-linux/usb/usbreceive.cpp index 4c453b0..142ab6f 100644 --- a/device/gxx-linux/usb/usbreceive.cpp +++ b/device/gxx-linux/usb/usbreceive.cpp @@ -37,7 +37,6 @@ int UsbReceive::read(MemoryPtr& memroy) int UsbReceive::read_bulk(void* data,unsigned int length) { - printf("(%p)perform read_bulk in UsbReceive object...\n", pthread_self()); int nread=0; if(usb.get()&&usb->is_connected()) { @@ -46,8 +45,6 @@ int UsbReceive::read_bulk(void* data,unsigned int length) else LOG_TRACE("read_bulk uncorrect data ptr or length"); } - printf("(%p)read_bulk in UsbReceive object OVER.\n", pthread_self()); - return nread; } diff --git a/device/gxx-linux/usb/usbservice.cpp b/device/gxx-linux/usb/usbservice.cpp index 97adaa0..dcbef6e 100644 --- a/device/gxx-linux/usb/usbservice.cpp +++ b/device/gxx-linux/usb/usbservice.cpp @@ -39,7 +39,6 @@ typedef struct static bool read_regs(unsigned int *regs, int regindex, int creg, std::shared_ptr ®sacess) { - printf("read_regs enter ...\n"); int index; for (int i = 0; i < creg; i++) { @@ -51,37 +50,31 @@ static bool read_regs(unsigned int *regs, int regindex, int creg, std::shared_pt } LOG_TRACE(string_format("read %d=%08x\n", index, regs[i])); } - printf("read_regs exit ...\n"); - return true; } static bool write_regs(unsigned int *regs, int regindex, int creg, std::shared_ptr ®sacess) { - printf("write_regs enter ...\n"); int index; - bool ret = true; for (int i = 0; i < creg; i++) { index = regindex + i; if (!regsacess->write(index, *(regs + i))) { LOG_ERROR(string_format("wirte error %d=%08x\n", index, regs[i])); - ret = false; - break; + return false; } LOG_TRACE(string_format("wirte %d=%08x\n", index, regs[i])); } - printf("write_regs exit.\n"); - return ret; + return true; } -UsbService::UsbService(std::shared_ptr fgparegs, std::shared_ptr motorregs, std::shared_ptr scannerregs) : devregs(scannerregs) +UsbService::UsbService(std::shared_ptr fgparegs, std::shared_ptr motorregs, std::shared_ptr scannerregs) { LOG_INIT(); this->fgparegs = fgparegs; this->motorregs = motorregs; - // this->devregs = scannerregs; + this->devregs = scannerregs; auto ctrl_handle = [&](int fd, struct usb_ctrlrequest *setup, unsigned char *buffer) -> bool { if(fd== -1) @@ -225,7 +218,6 @@ UsbService::UsbService(std::shared_ptr fgparegs, std::shared_ptrclear(); if (m_usbconnect) m_usbconnect(connected); @@ -237,15 +229,28 @@ UsbService::UsbService(std::shared_ptr fgparegs, std::shared_ptr UsbService::transmiter() { + // if(transmit.get()) + // { + // transmit.reset(); + // } + // transmit.reset(new UsbTransmit(usb)); + // return transmit; return transmit ? transmit : (transmit = std::shared_ptr(new UsbTransmit(usb))); } std::shared_ptr UsbService::receiver() { + // if(receiv.get()) + // { + // receiv.reset(); + // } + // receiv.reset(new UsbReceive(usb)); + // return receiv; return receiv ? receiv : (receiv = std::shared_ptr(new UsbReceive(usb))); } void UsbService::set_scannerregs(std::shared_ptr scannerregs) diff --git a/device/gxx-linux/usb/usbtransmit.cpp b/device/gxx-linux/usb/usbtransmit.cpp index 4456a4c..74a0d86 100644 --- a/device/gxx-linux/usb/usbtransmit.cpp +++ b/device/gxx-linux/usb/usbtransmit.cpp @@ -33,11 +33,12 @@ void UsbTransmit::write(MemoryPtr memroy) runthread.reset(new ThreadEx([this, memroy]() { if (usb && usb->is_connected()) { - LOG_TRACE("tx starting"); - LOG_TRACE(string_format("tx starting transfer index =%d mmy size = %d",++indextransfer,memroy->size())); + printf("tx starting"); + printf("tx starting transfer index =%d mmy size = %d",++indextransfer,memroy->size()); //printf("\n tx starting transfer index =%d mmy size = %d",++indextransfer,memroy->size()); int num= usb->write_bulk(memroy->data(), memroy->size()); - LOG_TRACE("tx end\n"); + printf("tx end\n"); + //printf("\n xfer size %d",num); } })); } diff --git a/device/gxx-linux/usb/vcxprj/usb.vcxproj b/device/gxx-linux/usb/vcxprj/usb.vcxproj index 1f716b4..c9a25cf 100644 --- a/device/gxx-linux/usb/vcxprj/usb.vcxproj +++ b/device/gxx-linux/usb/vcxprj/usb.vcxproj @@ -90,7 +90,7 @@ Level3 true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;ASYNC_EP;%(PreprocessorDefinitions) true @@ -159,13 +159,18 @@ - + + + + + + @@ -179,12 +184,17 @@ - + + + + + + diff --git a/device/gxx-linux/usb/vcxprj/usb.vcxproj.filters b/device/gxx-linux/usb/vcxprj/usb.vcxproj.filters index d3c7359..2b22dcc 100644 --- a/device/gxx-linux/usb/vcxprj/usb.vcxproj.filters +++ b/device/gxx-linux/usb/vcxprj/usb.vcxproj.filters @@ -25,6 +25,12 @@ {d6e1c6f0-7ff7-47f1-8bdb-a9c43abbcd5a} + + {2f453e58-2ad0-46fd-9961-0f4d62736f6a} + + + {77373ea7-32be-462b-ba5a-6388294577ce} + @@ -102,15 +108,30 @@ src\common\json - - src\common\json - src\common src\common + + src\imgproc + + + src\imgproc + + + src\imgproc + + + src\imgproc + + + src\hdw + + + src\common\json + @@ -161,15 +182,30 @@ src\common\json - - src\common\json - src\common src\common + + src\imgproc + + + src\imgproc + + + src\imgproc + + + src\imgproc + + + src\hdw + + + src\common\json + diff --git a/device/gxx-linux/usb/xmake.lua b/device/gxx-linux/usb/xmake.lua index b487997..d912033 100644 --- a/device/gxx-linux/usb/xmake.lua +++ b/device/gxx-linux/usb/xmake.lua @@ -3,9 +3,10 @@ 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*", "src/hardware/*.cpp") + add_files("*.cpp", "src/*.cpp", "src/async_model/common/*.cpp", "src/async_model/common/json/*.c*", "src/async_model/hardware/*.cpp", "src/async_model/img_process/*.cpp", "src/async_model/img_process/algs/*.cpp" + , "src/async_model/io/*.c*", "src/async_model/scanner/*.c*") add_includedirs("inc") - add_includedirs("src/common") + add_includedirs("src/async_model") add_includedirs(".", { public = true}) add_packages("common") - add_deps("regs", "gimgproc", "applog") \ No newline at end of file + add_deps("regs", "gimgproc", "applog", "capimage") \ No newline at end of file diff --git a/device/gxx-linux/xmake.lua b/device/gxx-linux/xmake.lua index dd76911..963efdb 100644 --- a/device/gxx-linux/xmake.lua +++ b/device/gxx-linux/xmake.lua @@ -1,6 +1,5 @@ set_project("GXX") - option("device") set_showmenu(true) set_default("g100") @@ -64,13 +63,9 @@ target("conf") set_configdir("$(buildir)/config") add_configfiles("config.h.in", {prefixdir = "header"}) add_includedirs("$(buildir)/config/header", { public = true }) -target_end("conf") -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/") +includes("regs", "deviceio", "motorboard", "capimage", "usb", "service", "scanner", "imgproc", "applog","scanservice","fpgaupdate","motorcontroller","display","testlcd","keymonitor","testkeymonitor","testdisplay","testwakeup") if has_config("testdemo") then - includes("testmotorboard", "testcapimage", "testusb", "testscanner", "testimgproc", "testregs") + includes("testmotorboard", "testcapimage", "testusb", "testscanner", "testimgproc", "testregs","testwakeup") end 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 16c2333..c99fa54 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 6520473..e654070 100644 --- a/pc/code_twain/sln/usb_tools/DlgScanner.cpp +++ b/pc/code_twain/sln/usb_tools/DlgScanner.cpp @@ -11,7 +11,7 @@ #define TIMER_ID_REFRESH_BULK 1001 #include -#include +#include HMODULE g_my_inst; @@ -262,7 +262,7 @@ namespace sane return sod; } - SANE_Option_Descriptor* trans_json_to_opt_desc(json* jsn) + SANE_Option_Descriptor* trans_json_to_opt_desc(gb_json* jsn) { std::string title(""), desc(""), @@ -281,7 +281,7 @@ namespace sane if (val == "string") { - json* range = NULL, * child = NULL; + gb_json* range = NULL, * child = NULL; jsn->get_value("range", range); if (range) @@ -302,7 +302,7 @@ namespace sane } else if (val == "int" || val == "float") { - json* range = NULL; + gb_json* range = NULL; jsn->get_value("range", range); if (range) @@ -324,7 +324,7 @@ namespace sane else { std::vector constraints; - json* child = range->first_child(); + gb_json* child = range->first_child(); while(child) { @@ -351,7 +351,7 @@ namespace sane else { std::vector constraints; - json* child = range->first_child(); + gb_json* child = range->first_child(); while(child) { @@ -423,12 +423,12 @@ namespace sane strcmp(ret->name, SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM) == 0) ret->unit = SANE_UNIT_MM; - //bool enabled = true; - //if (jsn->get_value("enable", enabled) && !enabled) - // ret->cap |= SANE_CAP_INACTIVE; + bool enabled = true; + if (jsn->get_value("enabled", enabled) && !enabled) + ret->cap |= SANE_CAP_INACTIVE; // 关联�? - json* depend = NULL; + gb_json* depend = NULL; } return ret; @@ -449,7 +449,7 @@ namespace sane if (json_txt) { - json* jsn = new json(), * child = NULL; + gb_json* jsn = new gb_json(), * child = NULL; if (jsn->attach_text((char*)json_txt)) { child = jsn->first_child(); @@ -494,7 +494,16 @@ namespace sane if (action == SANE_ACTION_GET_VALUE && option > 0 && option <= g_opts.size()) { - dlg->get_option(g_opts[option - 1]->name, value, g_opts[option - 1]->size); + if (g_opts[option - 1]->type == SANE_TYPE_FIXED) + { + double val = .0f; + dlg->get_option(g_opts[option - 1]->name, &val, sizeof(val)); + *(SANE_Fixed*)value = SANE_FIX(val); + } + else + { + dlg->get_option(g_opts[option - 1]->name, value, g_opts[option - 1]->size); + } return SANE_STATUS_GOOD; } @@ -517,13 +526,26 @@ namespace sane else val_size = strlen((char*)value); - SANE_Status ret = (SANE_Status)dlg->set_option(g_opts[option - 1]->name, value, g_opts[option - 1]->type, val_size, g_opts[option - 1]->size, (int*)info); + SANE_Int after = 0; + SANE_Status ret = (SANE_Status)dlg->set_option(g_opts[option - 1]->name, value, g_opts[option - 1]->type, val_size, g_opts[option - 1]->size, (int*)&after); + + if (info) + *info = after; if (buf == &val) { *(SANE_Int*)value = SANE_FIX(val); } + if (after & SANE_INFO_RELOAD_OPTIONS) + { + std::string str(""); + if (dlg->get_all_option(str) == 0) + { + reset_opts(str.c_str()); + } + } + return ret; } @@ -740,8 +762,17 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp) std::string root(usb::u2a(img_root_.c_str())); char name[40] = { 0 }; int err = 0; + std::string ext("jpg"); - sprintf_s(name, _countof(name) - 1, "scan_%04d.jpg", ++img_cnt_); + if (img->format == IMG_FMT_BMP) + ext = "bmp"; + else if (img->format == IMG_FMT_GIF) + ext = "gif"; + else if (img->format == IMG_FMT_PNG) + ext = "png"; + else if (img->format == IMG_FMT_TIFF) + ext = "tiff"; + sprintf_s(name, _countof(name) - 1, "scan_%04d.%s", ++img_cnt_, ext.c_str()); err = saver->open((root + name).c_str(), size); log_cls::log(LOG_LEVEL_DEBUG, "Begin receiving new image (%s + %llu) = %d\r\n", (root + name).c_str(), size, err); if (err) @@ -843,6 +874,17 @@ void CDlgScanner::get_option(const char* name, void* value, size_t size) { scanner_->option_value_get(name, value, size); } +int CDlgScanner::get_all_option(std::string& opts_json) +{ + int ret = scanner_->option_get_all(opts_json); + + if (ret == 0) + { + scanner_handler::reorder_device_config_json(opts_json); + } + + return ret; +} int CDlgScanner::set_option(const char* name, void* value, int type, size_t len, size_t max_len, int* after) { return scanner_->option_value_set(name, type, value, max_len, len, (uint8_t*)after); diff --git a/pc/code_twain/sln/usb_tools/DlgScanner.h b/pc/code_twain/sln/usb_tools/DlgScanner.h index 965e46f..e3d0e43 100644 --- a/pc/code_twain/sln/usb_tools/DlgScanner.h +++ b/pc/code_twain/sln/usb_tools/DlgScanner.h @@ -89,6 +89,7 @@ protected: public: void set_device(usb::LPUSBPNP pnp); void get_option(const char* name, void* value, size_t size); + int get_all_option(std::string& opts_json); int set_option(const char* name, void* value, int type, size_t len, size_t max_len, int* after); public: 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 b681a2d..9d394d7 100644 --- a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp +++ b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp @@ -3,7 +3,7 @@ #include "./usb/async_usb_host.h" #include -#include +#include @@ -259,7 +259,7 @@ bool scanner_handler::reorder_device_config_json(std::string& cont, const std::m typedef struct _grp_item { std::string name; - std::vector items; + std::vector items; bool operator==(const char* gn) { @@ -267,8 +267,8 @@ bool scanner_handler::reorder_device_config_json(std::string& cont, const std::m } }GRPITEM; std::vector items; - std::vector nogrp; - json* jsn = new json(), * child = nullptr; + std::vector nogrp; + gb_json* jsn = new gb_json(), * child = nullptr; bool ret = jsn->attach_text(&cont[0]); int cnt = 0; @@ -299,14 +299,14 @@ bool scanner_handler::reorder_device_config_json(std::string& cont, const std::m { nogrp.push_back(child); } - + child = jsn->next_child(); } jsn->release(); - child = new json(); + child = new gb_json(); child->set_value("option_count", cnt); - jsn = new json(); + jsn = new gb_json(); jsn->set_value("global", child); child->release(); @@ -326,7 +326,7 @@ bool scanner_handler::reorder_device_config_json(std::string& cont, const std::m if (it == items.end()) continue; - child = new json(); + child = new gb_json(); child->set_value("category", "base"); child->set_value("type", "group"); child->set_value("title", v.second.c_str()); @@ -344,7 +344,7 @@ bool scanner_handler::reorder_device_config_json(std::string& cont, const std::m for (auto& v : items) { - child = new json(); + child = new gb_json(); child->set_value("category", "base"); child->set_value("type", "group"); child->set_value("title", v.name.c_str()); 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 ba58747..df7f0c8 100644 --- a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h +++ b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h @@ -93,7 +93,7 @@ class scanner_handler : public refer public: scanner_handler(void); - // the json text from device only contains option items, the "group" info is contains in every item. + // the gb_json text from device only contains option items, the "group" info is contains in every item. // this function convert them into normal SANE-OPTION JSON // the parameter 'groups' is given the sequence of group static bool reorder_device_config_json(std::string& cont, const std::map* groups = nullptr); diff --git a/pc/code_twain/sln/usb_tools/usb_tools.vcxproj b/pc/code_twain/sln/usb_tools/usb_tools.vcxproj index 5e50a1c..e4bb095 100644 --- a/pc/code_twain/sln/usb_tools/usb_tools.vcxproj +++ b/pc/code_twain/sln/usb_tools/usb_tools.vcxproj @@ -29,14 +29,14 @@ Application true - v143 + v142 Unicode Dynamic Application false - v143 + v142 true Unicode Dynamic @@ -44,14 +44,14 @@ Application true - v143 + v142 Unicode Dynamic Application false - v143 + v142 true Unicode Dynamic @@ -77,7 +77,7 @@ true $(ProjectDir)..\..\..\sdk\include\;$(ProjectDir)..\..\device\win_usb\;$(ProjectDir)..\sdk\include\;$(ProjectDir)..\..\..\..\device\gxx-linux\usb\src\common\;$(IncludePath) - $(ProjectDir)..\sdk\lib\$(Configuration);$(ProjectDir)..\..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) + $(SolutionDir)sdk\lib\$(Configuration);$(ProjectDir)..\..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) true @@ -87,7 +87,7 @@ false $(ProjectDir)..\..\..\sdk\include\;$(ProjectDir)..\..\device\win_usb\;$(ProjectDir)..\sdk\include\;$(ProjectDir)..\..\..\..\device\gxx-linux\usb\src\common\;$(IncludePath) - $(ProjectDir)..\sdk\lib\$(Configuration);$(ProjectDir)..\..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) + $(SolutionDir)sdk\lib\$(Configuration);$(ProjectDir)..\..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) false @@ -200,7 +200,7 @@ - + @@ -246,9 +246,8 @@ NotUsing NotUsing - + NotUsing - NotUsing NotUsing diff --git a/pc/code_twain/sln/usb_tools/usb_tools.vcxproj.filters b/pc/code_twain/sln/usb_tools/usb_tools.vcxproj.filters index 3d650df..c8df840 100644 --- a/pc/code_twain/sln/usb_tools/usb_tools.vcxproj.filters +++ b/pc/code_twain/sln/usb_tools/usb_tools.vcxproj.filters @@ -81,9 +81,6 @@ Imports - - Imports - scanner @@ -105,6 +102,9 @@ opt-ui + + Imports + @@ -149,9 +149,6 @@ Imports - - Imports - scanner @@ -173,6 +170,9 @@ opt-ui + + Imports + diff --git a/pc/code_twain/sln/usb_tools/usb_toolsDlg.cpp b/pc/code_twain/sln/usb_tools/usb_toolsDlg.cpp index f3f8848..28877b3 100644 --- a/pc/code_twain/sln/usb_tools/usb_toolsDlg.cpp +++ b/pc/code_twain/sln/usb_tools/usb_toolsDlg.cpp @@ -267,12 +267,273 @@ namespace usb } +namespace test +{ + enum data_type1 + { + DATA_TYPE_BOOL = 0, // (bool*) + DATA_TYPE_INT1, // (uint8_t*) + DATA_TYPE_INT2, // (uint16_t*) + DATA_TYPE_INT4, // (uint32_t*) + DATA_TYPE_INT8, // (uint64_t*) + DATA_TYPE_FLOAT, // (double*) + DATA_TYPE_STRING, // (char*) with max_len space + DATA_TYPE_CUSTOM, + }; + + data_type1 type_from_string(const char* type_desc) + { + if (strcmp(type_desc, "bool") == 0) + return DATA_TYPE_BOOL; + if (strcmp(type_desc, "int") == 0) + return DATA_TYPE_INT4; + if (strcmp(type_desc, "float") == 0) + return DATA_TYPE_FLOAT; + if (strcmp(type_desc, "string") == 0) + return DATA_TYPE_STRING; + + return DATA_TYPE_CUSTOM; + } + bool try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) + { + bool oper_not = false, calc = true, handled = false; + size_t pos = exp.find("=="); + + if (pos == std::string::npos) + { + pos = exp.find("!="); + if (pos != std::string::npos) + { + oper_not = true; + } + } + if (pos != std::string::npos) + { + handled = true; + if (pos) + { + std::string types(""); + char buf[40] = { 0 }, * mem = nullptr; + size_t l = sizeof(buf) - 1; + + *name = exp.substr(0, pos); + get_opt(name->c_str(), buf, &l, "type"); + *type = type_from_string(buf); + l = 0; + get_opt(name->c_str(), mem, &l, "cur"); + mem = new char[l + 4]; + l += 4; + get_opt(name->c_str(), mem, &l, "cur"); + *val = std::string(mem, l); + delete[] mem; + } + exp.erase(0, pos + 2); + + if (*type == DATA_TYPE_BOOL) + { + calc = *(bool*)val->c_str() == (exp == "true"); + } + else if (*type == DATA_TYPE_INT4) + { + // in range ? + if (exp[0] == '[') + { + int lower = atoi(exp.c_str() + 1), + upper = 0; + pos = exp.find(","); + if (pos++ != std::string::npos) + upper = atoi(exp.c_str() + pos); + calc = lower <= *(int*)val->c_str() && *(int*)val->c_str() <= upper; + } + else + { + calc == *(int*)val->c_str() == atoi(exp.c_str()); + } + } + else if (*type == DATA_TYPE_FLOAT) + { + // in range ? + if (exp[0] == '[') + { + double lower = atof(exp.c_str() + 1), + upper = 0; + pos = exp.find(","); + if (pos++ != std::string::npos) + upper = atof(exp.c_str() + pos); + calc = lower <= *(double*)val->c_str() && *(double*)val->c_str() <= upper; + } + else + { + calc = IS_FLOAT_EQUAL(*(double*)val->c_str(), atof(exp.c_str())); + } + } + else if (*type == DATA_TYPE_STRING) + { + calc = *val == exp; + } + else + { + log_cls::log(LOG_LEVEL_FATAL, "Logic-operation error: un-supported type(%d) in '%s%s'\n", *type, oper_not ? "!=" : "==", exp.c_str()); + } + + *result = oper_not ^ calc; + } + + return handled; + } + bool try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) + { + bool oper_not = false, calc = true, handled = false; + size_t pos = exp.find(">"); + + if (pos == std::string::npos) + { + pos = exp.find("<="); + if (pos != std::string::npos) + { + oper_not = true; + } + } + if (pos != std::string::npos) + { + handled = true; + if (pos) + { + std::string types(""); + char buf[40] = { 0 }, * mem = nullptr; + size_t l = sizeof(buf) - 1; + + *name = exp.substr(0, pos); + get_opt(name->c_str(), buf, &l, "type"); + *type = type_from_string(buf); + l = 0; + get_opt(name->c_str(), mem, &l, "cur"); + mem = new char[l + 4]; + l += 4; + get_opt(name->c_str(), mem, &l, "cur"); + *val = std::string(mem, l); + delete[] mem; + } + exp.erase(0, pos + 1 + oper_not); + + if (*type == DATA_TYPE_INT4) + { + calc == *(int*)val->c_str() > atoi(exp.c_str()); + } + else if (*type == DATA_TYPE_FLOAT) + { + calc = *(double*)val->c_str() > atof(exp.c_str()); + } + else + { + log_cls::log(LOG_LEVEL_FATAL, "Logic-operation error: un-supported type(%d) in '%s%s'\n", *type, oper_not ? "<=" : ">", exp.c_str()); + } + + *result = oper_not ^ calc; + } + + return handled; + } + bool try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) + { + bool oper_not = false, calc = true, handled = false; + size_t pos = exp.find("<"); + + if (pos == std::string::npos) + { + pos = exp.find(">="); + if (pos != std::string::npos) + { + oper_not = true; + } + } + if (pos != std::string::npos) + { + handled = true; + if (pos) + { + std::string types(""); + char buf[40] = { 0 }, * mem = nullptr; + size_t l = sizeof(buf) - 1; + + *name = exp.substr(0, pos); + get_opt(name->c_str(), buf, &l, "type"); + *type = type_from_string(buf); + l = 0; + get_opt(name->c_str(), mem, &l, "cur"); + mem = new char[l + 4]; + l += 4; + get_opt(name->c_str(), mem, &l, "cur"); + *val = std::string(mem, l); + delete[] mem; + } + exp.erase(0, pos + 1 + oper_not); + + if (*type == DATA_TYPE_INT4) + { + calc == *(int*)val->c_str() < atoi(exp.c_str()); + } + else if (*type == DATA_TYPE_FLOAT) + { + calc = *(double*)val->c_str() < atof(exp.c_str()); + } + else + { + log_cls::log(LOG_LEVEL_FATAL, "Logic-operation error: un-supported type(%d) in '%s%s'\n", *type, oper_not ? ">=" : "<", exp.c_str()); + } + + *result = oper_not ^ calc; + } + + return handled; + } + bool is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt) + { + // ==, >, < + // !=, <=, >= + bool ok = true; + + if (!try_equal(exp, name, type, val, get_opt, &ok)) + { + if (!try_great(exp, name, type, val, get_opt, &ok)) + { + try_less(exp, name, type, val, get_opt, &ok); + } + } + + + return ok; + } +} + CusbtoolsDlg::CusbtoolsDlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_USB_TOOLS_DIALOG, pParent) { log_cls::initialize(NULL); log_cls::log(LOG_LEVEL_DEBUG, "--------------------New instance started ...--------------------\r\n"); + auto get_opt_val = [&](const char* cfg_name, void* buf, size_t* len, const char* key) -> int32_t + { + if (strcmp(key, "type") == 0) + strcpy((char*)buf, "bool"); + else if (strcmp(key, "cur") == 0) + { + if (*len < 1) + { + *len = 1; + return ENOMEM; + } + + *(bool*)buf = false; + *len = sizeof(bool); + } + + return 0; + }; + std::string exp("is-check-dog-ear==true"), name(""), val(""); + int type = 0; + bool chk = test::is_depends_item_ok(exp, &name, &type, &val, get_opt_val); + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }