2023-07-17 first
This commit is contained in:
parent
c563054e16
commit
cd5d017147
|
@ -0,0 +1,105 @@
|
||||||
|
#pragma once
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <deque>
|
||||||
|
#include <iostream>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class BlockingQueue
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
BlockingQueue(const BlockingQueue &rhs);
|
||||||
|
BlockingQueue &operator=(const BlockingQueue &rhs);
|
||||||
|
mutable std::mutex _mutex;
|
||||||
|
std::condition_variable _condvar;
|
||||||
|
std::deque<T> _queue;
|
||||||
|
bool isShutDown = false;
|
||||||
|
T tRet;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BlockingQueue()
|
||||||
|
: _mutex(), _condvar(), _queue()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~BlockingQueue()
|
||||||
|
{
|
||||||
|
ShutDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShutDown()
|
||||||
|
{
|
||||||
|
isShutDown = true;
|
||||||
|
_condvar.notify_all();
|
||||||
|
_queue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsShutDown()
|
||||||
|
{
|
||||||
|
return isShutDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
//β²å
|
||||||
|
void Put(const T task)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
if (!isShutDown)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
_queue.push_back(task);
|
||||||
|
}
|
||||||
|
_condvar.notify_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Í·È¡
|
||||||
|
T Take()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(_mutex);
|
||||||
|
if (_queue.size() <= 0)
|
||||||
|
_condvar.wait(lock);
|
||||||
|
|
||||||
|
if (isShutDown || _queue.empty())
|
||||||
|
{
|
||||||
|
return tRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
T front(_queue.front());
|
||||||
|
_queue.pop_front();
|
||||||
|
|
||||||
|
return front;
|
||||||
|
}
|
||||||
|
|
||||||
|
T Front()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(_mutex);
|
||||||
|
if (_queue.size() <= 0)
|
||||||
|
_condvar.wait(lock);
|
||||||
|
|
||||||
|
if (isShutDown || _queue.empty())
|
||||||
|
{
|
||||||
|
return tRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
T front(_queue.front());
|
||||||
|
return front;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Size() const
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
return _queue.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(_mutex);
|
||||||
|
if (_queue.size() <= 0)
|
||||||
|
return;
|
||||||
|
if (_queue.size()>0)
|
||||||
|
{
|
||||||
|
_queue.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,140 @@
|
||||||
|
// #include "CImageMerge.h"
|
||||||
|
// #include <sstream>
|
||||||
|
|
||||||
|
// CImageMerge::CImageMerge()
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
// CImageMerge::~CImageMerge()
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat CImageMerge::MergeImage(cv::Mat &srcMat, int dstwidth, int dstheight,int mode)
|
||||||
|
// {
|
||||||
|
// cv::Mat dst(srcMat.rows, srcMat.cols / (mode == 0 ? 1:3), CV_8UC(mode == 0 ? 1 : 3));
|
||||||
|
// auto graymerge = [](cv::Mat& src,cv::Mat dst)->cv::Mat{
|
||||||
|
// int width_block = src.cols / 12;
|
||||||
|
// int heigh_block = src.rows;
|
||||||
|
|
||||||
|
// // 20 vsp 拼接算法
|
||||||
|
// // src(cv::Rect(width_block,0,width_block*2,heigh_block)).copyTo(dst(cv::Rect(0,0,width_block*2,heigh_block)));
|
||||||
|
// // src(cv::Rect(0,0,width_block,heigh_block)).copyTo(dst(cv::Rect(width_block*2,0,width_block,heigh_block)));
|
||||||
|
// // src(cv::Rect(width_block*3,0,width_block*2,heigh_block)).copyTo(dst(cv::Rect(width_block*4,0,width_block*2,heigh_block)));
|
||||||
|
// // src(cv::Rect(width_block*5,0,width_block,heigh_block)).copyTo(dst(cv::Rect(width_block*3,0,width_block,heigh_block)));
|
||||||
|
|
||||||
|
// // src(cv::Rect(width_block*7,0,width_block*2,heigh_block)).copyTo(dst(cv::Rect(width_block*6,0,width_block*2,heigh_block)));
|
||||||
|
// // src(cv::Rect(width_block*6,0,width_block,heigh_block)).copyTo(dst(cv::Rect(width_block*8,0,width_block,heigh_block)));
|
||||||
|
// // src(cv::Rect(width_block*9,0,width_block*2,heigh_block)).copyTo(dst(cv::Rect(width_block*10,0,width_block*2,heigh_block)));
|
||||||
|
// // src(cv::Rect(width_block*11,0,width_block,heigh_block)).copyTo(dst(cv::Rect(width_block*9,0,width_block,heigh_block)));
|
||||||
|
// //return dst;
|
||||||
|
|
||||||
|
// // 45 vsp 拼接算法
|
||||||
|
// src(cv::Rect(0,0,width_block*2,heigh_block)).copyTo(dst(cv::Rect(width_block,0,width_block*2,heigh_block)));
|
||||||
|
// src(cv::Rect(width_block*2,0,width_block,heigh_block)).copyTo(dst(cv::Rect(0,0,width_block,heigh_block)));
|
||||||
|
// src(cv::Rect(width_block*3,0,width_block,heigh_block)).copyTo(dst(cv::Rect(width_block*5,0,width_block,heigh_block)));
|
||||||
|
// src(cv::Rect(width_block*4,0,width_block*2,heigh_block)).copyTo(dst(cv::Rect(width_block*3,0,width_block*2,heigh_block)));
|
||||||
|
|
||||||
|
// src(cv::Rect(width_block*6,0,width_block*2,heigh_block)).copyTo(dst(cv::Rect(width_block*7,0,width_block*2,heigh_block)));
|
||||||
|
// src(cv::Rect(width_block*8,0,width_block,heigh_block)).copyTo(dst(cv::Rect(width_block*6,0,width_block,heigh_block)));
|
||||||
|
// src(cv::Rect(width_block*9,0,width_block,heigh_block)).copyTo(dst(cv::Rect(width_block*11,0,width_block,heigh_block)));
|
||||||
|
// src(cv::Rect(width_block*10,0,width_block*2,heigh_block)).copyTo(dst(cv::Rect(width_block*9,0,width_block*2,heigh_block)));
|
||||||
|
// return dst;
|
||||||
|
|
||||||
|
// };
|
||||||
|
// //cv::imwrite("org.jpg",srcMat);
|
||||||
|
// if (!srcMat.empty())
|
||||||
|
// {
|
||||||
|
// if(mode == 0)//灰度模式
|
||||||
|
// return graymerge(srcMat,dst);
|
||||||
|
|
||||||
|
// std::vector<cv::Mat> ch_mats;
|
||||||
|
// int blockcnt = 12;
|
||||||
|
// int spitWidth = srcMat.cols / blockcnt;
|
||||||
|
// cv::Mat retMat(srcMat.rows, srcMat.cols / 3, CV_8UC3);
|
||||||
|
// for (int i = 0; i < 4; i++)
|
||||||
|
// {
|
||||||
|
// if (i < 2)
|
||||||
|
// {
|
||||||
|
// ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 1), 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 + 0), 0, spitWidth, srcMat.rows)));
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 1), 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 + 2), 0, spitWidth, srcMat.rows)));
|
||||||
|
// }
|
||||||
|
// cv::merge(ch_mats, retMat(cv::Rect(spitWidth * i, 0, spitWidth, srcMat.rows)));
|
||||||
|
// ch_mats.clear();
|
||||||
|
// }
|
||||||
|
// return graymerge(retMat,dst);
|
||||||
|
// }
|
||||||
|
// return srcMat;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat CImageMerge::MergeImage(bool iscolor, cv::Mat &srcMat, int dstwidth, int dstheight)
|
||||||
|
// {
|
||||||
|
// 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();
|
||||||
|
// return dst;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// std::vector<cv::Mat> m_splits;
|
||||||
|
// std::vector<int> m_index = {1, 4, 7, 10, 2, 5, 6, 9, 0, 3, 8, 11};
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat CImageMerge::MergeFrames(std::vector<cv::Mat> frames, int type, int dpi)
|
||||||
|
// {
|
||||||
|
// if (frames.empty())
|
||||||
|
// return cv::Mat();
|
||||||
|
|
||||||
|
// int size = frames.size();
|
||||||
|
// auto it = frames.begin();
|
||||||
|
// int dstH = it->rows * size;
|
||||||
|
// int abortwidth = dpi == 0x02 || dpi == 0x01 ? 432 : 864; // 216*2 432*2
|
||||||
|
// int dstwidth = dpi == 0x02 || dpi == 0x01 ? 7344 : 14688;
|
||||||
|
// cv::Mat matdst(dstH, dstwidth, CV_8UC(type == 1 ? 3 : 1));
|
||||||
|
// for (int i = 0; i < size; i++)
|
||||||
|
// {
|
||||||
|
// auto itemimg = frames[i];
|
||||||
|
// itemimg = MergeImage(type, itemimg, dstwidth + abortwidth, itemimg.rows);
|
||||||
|
// itemimg.copyTo(matdst(cv::Rect(0, itemimg.rows * i, itemimg.cols, itemimg.rows)));
|
||||||
|
// itemimg.release();
|
||||||
|
// }
|
||||||
|
// return matdst;
|
||||||
|
// }
|
|
@ -0,0 +1,15 @@
|
||||||
|
// #pragma once
|
||||||
|
// #include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
// class CImageMerge
|
||||||
|
// {
|
||||||
|
// private:
|
||||||
|
// /* data */
|
||||||
|
// public:
|
||||||
|
// CImageMerge(/* args */);
|
||||||
|
// ~CImageMerge();
|
||||||
|
// public:
|
||||||
|
// cv::Mat MergeImage(cv::Mat& srcMat,int dstwidth,int dstheight,int mode);
|
||||||
|
// cv::Mat MergeImage(bool iscolor,cv::Mat& srcMat,int dstwidth,int dstheight);
|
||||||
|
// cv::Mat MergeFrames(std::vector<cv::Mat> frames, int type, int dpi);
|
||||||
|
// };
|
|
@ -0,0 +1,79 @@
|
||||||
|
cmake_minimum_required(VERSION 3.0.0)
|
||||||
|
project(scanservice)
|
||||||
|
add_compile_options(-std=c++14)
|
||||||
|
#set (CMAKE_GENERATOR "/home/holdtecs/zzm-linux/rk3288-linux/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#交叉编译配置
|
||||||
|
# set(CMAKE_SYSTEM_NAME Linux)
|
||||||
|
# set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||||
|
|
||||||
|
#可选,配置roofs和安装路径如果存在
|
||||||
|
#set(linux_sdk_path /home/holdtecs/zzm-linux/rk3288-linux)
|
||||||
|
#set(linux_sdk_path /mnt/disk2/linux-rhx/rk3288-linux)
|
||||||
|
#set(CMAKE_SYSROOT ${linux_sdk_path}/buildroot/output/rockchip_rk3288/host/arm-buildroot-linux-gnueabihf/sysroot)
|
||||||
|
# set(CMAKE_STAGING_PREFIX ${PROJECT_SOURCE_DIR}/install)
|
||||||
|
|
||||||
|
#编译工具配置
|
||||||
|
#set(tools ${linux_sdk_path}/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf)
|
||||||
|
# set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||||
|
# set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||||
|
# set(CMAKE_LIBRARY_ARCHITECTURE arm)
|
||||||
|
|
||||||
|
set(-mfloat-abi=hard)
|
||||||
|
|
||||||
|
# set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
# set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
# set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
# set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||||
|
|
||||||
|
set(OpenCV_DIR /home/modehua/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/include/opencv4/)
|
||||||
|
#set(OpenCV_DIR /home/holdtecs/zzm-linux/fs/usr/lib)
|
||||||
|
#find_package( OpenCV 3 REQUIRED )
|
||||||
|
include_directories( ${OpenCV_INCLUDE_DIRS} )
|
||||||
|
|
||||||
|
FILE(GLOB SRC "*.cpp" "*.h" "*.c")
|
||||||
|
FILE(GLOB IMAGEPRO "imageprocess/*.h" "imageprocess/*.cpp" )
|
||||||
|
FILE(GLOB FPGA "fpga/*.h" "fpga/*.cpp" )
|
||||||
|
# message(STATUS "SRC:" ${SRC})
|
||||||
|
# message(STATUS "IMAGEPRO:" ${IMAGEPRO})
|
||||||
|
#message(STATUS "FPGA:" ${FPGA})
|
||||||
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
fpga
|
||||||
|
imageprocess
|
||||||
|
imageprocess/include
|
||||||
|
#/home/modehua/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/include/opencv4/
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${SRC})
|
||||||
|
|
||||||
|
#优化代码大小
|
||||||
|
SET(-CMAKE_BUILD_TYPE "Release")
|
||||||
|
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||||
|
|
||||||
|
|
||||||
|
add_custom_command(TARGET ${PROJECT_NAME}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND $ENV{STRIP} -s ${PROJECT_NAME})
|
||||||
|
|
||||||
|
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE "-s")
|
||||||
|
|
||||||
|
#target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS} pthread)
|
||||||
|
message(/home/modehua/sdk/scanservices/scanservices/fpga/bin/libfpgaupdate.a)
|
||||||
|
target_link_libraries(${PROJECT_NAME} /home/modehua/sdk/scanservices/scanservices/fpga/bin/libfpgaupdate.a)
|
||||||
|
#target_link_libraries(${PROJECT_NAME} opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs turbojpeg pthread )
|
||||||
|
target_link_libraries(${PROJECT_NAME} pthread )
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}
|
||||||
|
|
||||||
|
${PROJECT_SOURCE_DIR}/fpga
|
||||||
|
${PROJECT_SOURCE_DIR}/imageprocess
|
||||||
|
${PROJECT_SOURCE_DIR}/imageprocess/include
|
||||||
|
${PROJECT_SOURCE_DIR}/home/modehua/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/include/opencv4/
|
||||||
|
)
|
|
@ -0,0 +1,292 @@
|
||||||
|
// #include "CSizedetect.h"
|
||||||
|
// #include <opencv2/opencv.hpp>
|
||||||
|
// #include "ImageProcess_Public.h"
|
||||||
|
// #include "opencv2/imgproc/types_c.h"
|
||||||
|
// #include "opencv2/imgproc/imgproc_c.h"
|
||||||
|
// void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre)
|
||||||
|
// {
|
||||||
|
// if (src.channels() == 3)
|
||||||
|
// {
|
||||||
|
// #ifdef USE_ONENCL
|
||||||
|
// if (cl_res.context)
|
||||||
|
// transforColor_threshold_opencl(src, dst, static_cast<uchar>(thre));
|
||||||
|
// else
|
||||||
|
// #endif
|
||||||
|
// {
|
||||||
|
// cv::Mat gray = hg::transforColor(src);
|
||||||
|
// cv::threshold(gray, dst, thre, 255, cv::THRESH_BINARY);
|
||||||
|
// gray.release();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// cv::threshold(src, dst, thre, 255, cv::THRESH_BINARY);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset)
|
||||||
|
// {
|
||||||
|
// #if CV_VERSION_REVISION == 6
|
||||||
|
// CvMat c_image = src;
|
||||||
|
// #else
|
||||||
|
// CvMat c_image;
|
||||||
|
// c_image = cvMat(src.rows, src.cols, src.type(), src.data);
|
||||||
|
// c_image.step = src.step[0];
|
||||||
|
// c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (src.flags & cv::Mat::CONTINUOUS_FLAG);
|
||||||
|
// #endif
|
||||||
|
// cv::MemStorage storage(cvCreateMemStorage());
|
||||||
|
// CvSeq* _ccontours = nullptr;
|
||||||
|
|
||||||
|
// #if CV_VERSION_REVISION == 6
|
||||||
|
// cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset));
|
||||||
|
// #else
|
||||||
|
// cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint{ offset.x, offset.y });
|
||||||
|
// #endif
|
||||||
|
// if (!_ccontours)
|
||||||
|
// {
|
||||||
|
// contours.clear();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// cv::Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
|
||||||
|
// size_t total = all_contours.size();
|
||||||
|
// contours.resize(total);
|
||||||
|
|
||||||
|
// cv::SeqIterator<CvSeq*> it = all_contours.begin();
|
||||||
|
// for (size_t i = 0; i < total; i++, ++it)
|
||||||
|
// {
|
||||||
|
// CvSeq* c = *it;
|
||||||
|
// reinterpret_cast<CvContour*>(c)->color = static_cast<int>(i);
|
||||||
|
// int count = c->total;
|
||||||
|
// int* data = new int[static_cast<size_t>(count * 2)];
|
||||||
|
// cvCvtSeqToArray(c, data);
|
||||||
|
// for (int j = 0; j < count; j++)
|
||||||
|
// {
|
||||||
|
// contours[i].push_back(cv::Point(data[j * 2], data[j * 2 + 1]));
|
||||||
|
// }
|
||||||
|
// delete[] data;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// hierarchy.resize(total);
|
||||||
|
// it = all_contours.begin();
|
||||||
|
// for (size_t i = 0; i < total; i++, ++it)
|
||||||
|
// {
|
||||||
|
// CvSeq* c = *it;
|
||||||
|
// int h_next = c->h_next ? reinterpret_cast<CvContour*>(c->h_next)->color : -1;
|
||||||
|
// int h_prev = c->h_prev ? reinterpret_cast<CvContour*>(c->h_prev)->color : -1;
|
||||||
|
// int v_next = c->v_next ? reinterpret_cast<CvContour*>(c->v_next)->color : -1;
|
||||||
|
// int v_prev = c->v_prev ? reinterpret_cast<CvContour*>(c->v_prev)->color : -1;
|
||||||
|
// hierarchy[i] = cv::Vec4i(h_next, h_prev, v_next, v_prev);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// storage.release();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::vector<cv::Point> getMaxContour(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy)
|
||||||
|
// {
|
||||||
|
// std::vector<cv::Point> maxContour;
|
||||||
|
// if (contours.size() < 1) return {};
|
||||||
|
|
||||||
|
// for (size_t i = 0, length = hierarchy.size(); i < length; i++)
|
||||||
|
// if (hierarchy[i][3] == -1)
|
||||||
|
// for (const auto& item : contours[i])
|
||||||
|
// maxContour.push_back(item);
|
||||||
|
|
||||||
|
// return maxContour;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour)
|
||||||
|
// {
|
||||||
|
// if (contour.empty()) return {};
|
||||||
|
|
||||||
|
// cv::RotatedRect rect = minAreaRect(contour);
|
||||||
|
// if (rect.angle < -45)
|
||||||
|
// {
|
||||||
|
// rect.angle += 90;
|
||||||
|
// float temp = rect.size.width;
|
||||||
|
// rect.size.width = rect.size.height;
|
||||||
|
// rect.size.height = temp;
|
||||||
|
// }
|
||||||
|
// if (rect.angle > 45)
|
||||||
|
// {
|
||||||
|
// rect.angle -= 90;
|
||||||
|
// float temp = rect.size.width;
|
||||||
|
// rect.size.width = rect.size.height;
|
||||||
|
// rect.size.height = temp;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return rect;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// CSizedetect::CSizedetect(int papaertype,int dpi) : m_papertype(papaertype),
|
||||||
|
// m_horThre(70),
|
||||||
|
// m_verThre(100),
|
||||||
|
// m_dpi(dpi)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// CSizedetect::~CSizedetect(void) {}
|
||||||
|
|
||||||
|
// void CSizedetect::SetPapertype(int papertype) {
|
||||||
|
// m_papertype=papertype;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static int x=0;
|
||||||
|
// int CSizedetect::preprocess(cv::Mat &mat, void *unused)
|
||||||
|
// {
|
||||||
|
// if(!mat.empty())
|
||||||
|
// {
|
||||||
|
// float width, height;
|
||||||
|
// cv::Mat thre;
|
||||||
|
// hg::threshold_Mat(mat, thre, 40);
|
||||||
|
// cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(8, 1));
|
||||||
|
// cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
|
||||||
|
// std::vector<std::vector<cv::Point>> contours;
|
||||||
|
// std::vector<cv::Vec4i> hierarchy;
|
||||||
|
// hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
|
||||||
|
// std::vector<cv::Point> maxContour = hg::getMaxContour(contours, hierarchy);
|
||||||
|
// cv::RotatedRect rect = hg::getBoundingRect(maxContour);
|
||||||
|
// width = rect.size.width;
|
||||||
|
// height = rect.size.height;
|
||||||
|
// //fastMeasureSize(mat.data,mat.cols,mat.rows,mat.channels(),width,height,40,20,5);
|
||||||
|
// HGSize dstSize;
|
||||||
|
// if(m_supportPaper.count((PaperSize)m_papertype)>0)//包含设置的幅面
|
||||||
|
// {
|
||||||
|
// dstSize=m_supportPaper[(PaperSize)m_papertype];
|
||||||
|
// if(m_dpi==0x02||m_dpi==0x03)
|
||||||
|
// {
|
||||||
|
// float ratio = m_dpi==0x02? 1.5f : 3.0f;
|
||||||
|
// dstSize.width*=ratio;
|
||||||
|
// dstSize.height*=ratio;
|
||||||
|
// }
|
||||||
|
// LOG("mat_width =%.2f ,mat_height = %.2f std_width = %df std_height=%df m_dpi = %d \n",width,height,dstSize.width,dstSize.height,m_dpi);
|
||||||
|
// if((width>(dstSize.width+m_horThre))||(width<(dstSize.width-m_horThre))||(height > (dstSize.height+m_verThre))||(height < (dstSize.height-m_verThre)))
|
||||||
|
// {
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void CSizedetect::rotate(float &x, float &y, float angle)
|
||||||
|
// {
|
||||||
|
// float a = x * cos(angle) - y * sin(angle);
|
||||||
|
// float b = x * sin(angle) + y * cos(angle);
|
||||||
|
// x = a;
|
||||||
|
// y = b;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void CSizedetect::minAeaRect(const float *x, const float *y, int size, float &width, float &height)
|
||||||
|
// {
|
||||||
|
// float area = width * height;
|
||||||
|
// // rotate 0~90 degree
|
||||||
|
// for (int i = 0; i < 91; ++i)
|
||||||
|
// {
|
||||||
|
// float tmpx = x[0], tmpy = y[0];
|
||||||
|
// rotate(tmpx, tmpy, i);
|
||||||
|
// float xl = tmpx, xr = tmpx, yt = tmpy, yb = tmpy;
|
||||||
|
// // traverse all points
|
||||||
|
// for (int j = 1; j < size; ++j)
|
||||||
|
// {
|
||||||
|
// tmpx = x[j];
|
||||||
|
// tmpy = y[j];
|
||||||
|
// rotate(tmpx, tmpy, i);
|
||||||
|
// if (tmpx < xl)
|
||||||
|
// xl = tmpx;
|
||||||
|
// if (tmpx > xr)
|
||||||
|
// xr = tmpx;
|
||||||
|
// if (tmpy < yb)
|
||||||
|
// yb = tmpy;
|
||||||
|
// if (tmpy > yt)
|
||||||
|
// yt = tmpy;
|
||||||
|
// }
|
||||||
|
// float xx = xr - xl, yy = yt - yb;
|
||||||
|
// if (area > xx * yy)
|
||||||
|
// {
|
||||||
|
// area = xx * yy;
|
||||||
|
// height = xx;
|
||||||
|
// width = yy;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// if (height < width)
|
||||||
|
// {
|
||||||
|
// float tmp = height;
|
||||||
|
// height = width;
|
||||||
|
// width = tmp;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void CSizedetect::fastMeasureSize(const unsigned char *data, int src_width, int src_height, int channels, float &dst_width, float &dst_height, int threshold, int indent, int step)
|
||||||
|
// {
|
||||||
|
// int bytesPerLine = src_width * channels;
|
||||||
|
// int indent_x = indent * channels;
|
||||||
|
// int indent_y = indent;
|
||||||
|
// int step_x = step * channels;
|
||||||
|
// int step_y = step;
|
||||||
|
|
||||||
|
// int total_count = (bytesPerLine + src_height) * 2 / indent;
|
||||||
|
// if (total_count < 1)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// float *points_x = new float[total_count];
|
||||||
|
// float *points_y = new float[total_count];
|
||||||
|
|
||||||
|
// int points_count = 0;
|
||||||
|
// //top
|
||||||
|
// int rows = src_height / 2;
|
||||||
|
// for (int x = 0; x < bytesPerLine; x += indent_x)
|
||||||
|
// for (int y = 0; y < rows; y += step_y)
|
||||||
|
// if (data[y * bytesPerLine + x] > threshold)
|
||||||
|
// {
|
||||||
|
// points_x[points_count] = x / channels;
|
||||||
|
// points_y[points_count] = y;
|
||||||
|
// points_count++;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //bottom
|
||||||
|
// for (int x = 0; x < bytesPerLine; x += indent_x)
|
||||||
|
// for (int y = src_height - 1; y >= rows; y -= step_y)
|
||||||
|
// if (data[y * bytesPerLine + x] > threshold)
|
||||||
|
// {
|
||||||
|
// points_x[points_count] = x / channels;
|
||||||
|
// points_y[points_count] = y;
|
||||||
|
// points_count++;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //left
|
||||||
|
// int cols = bytesPerLine / 2;
|
||||||
|
// for (int y = 0; y < src_height; y += indent)
|
||||||
|
// for (int x = 0; x < cols; x += step_x)
|
||||||
|
// if (data[y * bytesPerLine + x] > threshold)
|
||||||
|
// {
|
||||||
|
// points_x[points_count] = x / channels;
|
||||||
|
// points_y[points_count] = y;
|
||||||
|
// points_count++;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //right
|
||||||
|
// for (int y = 0; y < src_height; y += indent)
|
||||||
|
// for (int x = bytesPerLine - 1; x >= cols; x -= step_x)
|
||||||
|
// if (data[y * bytesPerLine + x] > threshold)
|
||||||
|
// {
|
||||||
|
// points_x[points_count] = x / channels;
|
||||||
|
// points_y[points_count] = y;
|
||||||
|
// points_count++;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (points_count > 3)
|
||||||
|
// {
|
||||||
|
// dst_width = src_width;
|
||||||
|
// dst_height = src_height;
|
||||||
|
// minAeaRect(points_x, points_y, points_count, dst_width, dst_height);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// delete[] points_x;
|
||||||
|
// delete[] points_y;
|
||||||
|
// }
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
// #pragma once
|
||||||
|
// #include "IPreproc.h"
|
||||||
|
// #include <map>
|
||||||
|
// #include "scanservices_utils.h"
|
||||||
|
|
||||||
|
// class CSizedetect : public IPreproc
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// explicit CSizedetect(int papaertype,int dpi);
|
||||||
|
// virtual ~CSizedetect(void);
|
||||||
|
// virtual int preprocess(cv::Mat& mat,void* unused);
|
||||||
|
// void SetPapertype(int papertype);
|
||||||
|
// private:
|
||||||
|
// void rotate(float& x, float& y, float angle);
|
||||||
|
// void minAeaRect(const float* x, const float* y, int size, float& width, float& height);
|
||||||
|
// void fastMeasureSize(const unsigned char* data, int src_width, int src_height, int channels, float& dst_width, float& dst_height, int threshold = 40, int indent = 20, int step = 5);
|
||||||
|
// private:
|
||||||
|
// int m_papertype;
|
||||||
|
// int m_horThre;
|
||||||
|
// int m_verThre;
|
||||||
|
// int m_dpi;
|
||||||
|
// std::map<PaperSize,HGSize> m_supportPaper={
|
||||||
|
// {PaperSize::G400_A3,HGSize{2338,3307}},
|
||||||
|
// {PaperSize::G400_A4,HGSize{1653,2338}},
|
||||||
|
// {PaperSize::G400_A4R,HGSize{2338,1653}},
|
||||||
|
// {PaperSize::G400_A5,HGSize{1165,1653}},
|
||||||
|
// {PaperSize::G400_A5R,HGSize{1653,1165}},
|
||||||
|
// {PaperSize::G400_A6,HGSize{826,1165}},
|
||||||
|
// {PaperSize::G400_A6R,HGSize{1165,826}},
|
||||||
|
// {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,3401}},
|
||||||
|
// {PaperSize::G400_LEGAL,HGSize{1700,2800}},
|
||||||
|
// {PaperSize::G400_LETTER,HGSize{1700,2198}},
|
||||||
|
// {PaperSize::G400_LETTERR,HGSize{2198,1700}},
|
||||||
|
// {PaperSize::G400_LONGLETTER,HGSize{2040,2640}},
|
||||||
|
// {PaperSize::G400_MAXSIZE,HGSize{2338,6614}}
|
||||||
|
// };
|
||||||
|
// };
|
|
@ -0,0 +1,41 @@
|
||||||
|
#pragma once
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
//#define LIGHT_DIFF(maxthre, x) ((maxthre)-x)
|
||||||
|
#define LIGHT_DIFF(x) (200 - x)
|
||||||
|
#define BLACK_DIFF(x) (8.0 - x)
|
||||||
|
#define FMT_STEP(x) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (x < 1 && x > 0) \
|
||||||
|
{ \
|
||||||
|
x = 1; \
|
||||||
|
} \
|
||||||
|
if (step < 0 && step > -1) \
|
||||||
|
{ \
|
||||||
|
x = -1; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
struct FPGAConfigParam
|
||||||
|
{
|
||||||
|
unsigned int ExposureF[3]; //RGB
|
||||||
|
unsigned int GainF[6]; //123456
|
||||||
|
unsigned int OffsetF[6]; //123456
|
||||||
|
unsigned int ExposureB[3]; //RGB
|
||||||
|
unsigned int GainB[6]; //123456
|
||||||
|
unsigned int OffsetB[6]; //123456
|
||||||
|
unsigned int DpiMode;
|
||||||
|
unsigned int ColorMode;
|
||||||
|
unsigned int MaxBright;
|
||||||
|
unsigned int MaxExp;
|
||||||
|
unsigned int Sp;
|
||||||
|
unsigned int HRatio;
|
||||||
|
unsigned int VRatio;
|
||||||
|
std::string LutPath;
|
||||||
|
std::string TextLutPath;
|
||||||
|
std::string Flat_BwPath;
|
||||||
|
std::string Flat_WhitePath;
|
||||||
|
};
|
|
@ -0,0 +1,2 @@
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
|
@ -0,0 +1,403 @@
|
||||||
|
#include "CorrectParam.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define JSONPATH "/usr/local/huago/cameraparam.json"
|
||||||
|
|
||||||
|
#define TEXTLUT200COLORPATH "/usr/local/huago/Textlut200clr.bmp"
|
||||||
|
#define LUT200COLORPATH "/usr/local/huago/lut200clr.bmp"
|
||||||
|
#define LUT200_COLOR_BLACKPATH "/usr/local/huago/lut200clrbw.bmp"
|
||||||
|
#define LUT200_COLOR_WHITEPATH "/usr/local/huago/lut200clrwhite.bmp"
|
||||||
|
|
||||||
|
#define TEXTLUT200GRAYPATH "/usr/local/huago/Textlut200gray.bmp"
|
||||||
|
#define LUT200GRAYPATH "/usr/local/huago/lut200gray.bmp"
|
||||||
|
#define LUT200_GRAY_BLACKPATH "/usr/local/huago/lut200graybw.bmp"
|
||||||
|
#define LUT200_GRAY_WHITEPATH "/usr/local/huago/lut200graywhite.bmp"
|
||||||
|
|
||||||
|
#define TEXTLUT300COLORPATH "/usr/local/huago/Textlut300clr.bmp"
|
||||||
|
#define LUT300COLORPATH "/usr/local/huago/lut300clr.bmp"
|
||||||
|
#define LUT300_COLOR_BLACKPATH "/usr/local/huago/lut300clrbw.bmp"
|
||||||
|
#define LUT300_COLOR_WHITEPATH "/usr/local/huago/lut300clrwhite.bmp"
|
||||||
|
|
||||||
|
#define TEXTLUT300GRAYPATH "/usr/local/huago/Textlut300gray.bmp"
|
||||||
|
#define LUT300GRAYPATH "/usr/local/huago/lut300gray.bmp"
|
||||||
|
#define LUT300_GRAY_BLACKPATH "/usr/local/huago/lut300graybw.bmp"
|
||||||
|
#define LUT300_GRAY_WHITEPATH "/usr/local/huago/lut300graywhite.bmp"
|
||||||
|
|
||||||
|
#define LUT600COLORPATH "/usr/local/huago/lut600clr.bmp"
|
||||||
|
#define TEXTLUT600COLORPATH "/usr/local/huago/Textlut600clr.bmp"
|
||||||
|
#define LUT600_COLOR_BLACKPATH "/usr/local/huago/lut600clrbw.bmp"
|
||||||
|
#define LUT600_COLOR_WHITEPATH "/usr/local/huago/lut600clrwhite.bmp"
|
||||||
|
|
||||||
|
#define LUT600GRAYPATH "/usr/local/huago/lut600gray.bmp"
|
||||||
|
#define TEXTLUT600GRAYPATH "/usr/local/huago/Textlut600gray.bmp"
|
||||||
|
#define LUT600_GRAY_BLACKPATH "/usr/local/huago/lut600graybw.bmp"
|
||||||
|
#define LUT600_GRAY_WHITEPATH "/usr/local/huago/lut600graywhite.bmp"
|
||||||
|
|
||||||
|
CorrectParam::CorrectParam()
|
||||||
|
{
|
||||||
|
initdefaultpapram();
|
||||||
|
}
|
||||||
|
|
||||||
|
CorrectParam::~CorrectParam()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<FPGAConfigParam> CorrectParam::GetCorrectParams()
|
||||||
|
{
|
||||||
|
struct stat buff;
|
||||||
|
if (stat(JSONPATH, &buff) != 0)//不存在
|
||||||
|
{
|
||||||
|
initdefaultpapram();
|
||||||
|
}
|
||||||
|
std::lock_guard<std::mutex> lc(m_lc);
|
||||||
|
std::ifstream i(JSONPATH);
|
||||||
|
json j;
|
||||||
|
i >> j;
|
||||||
|
std::vector<FPGAConfigParam> vct_param;
|
||||||
|
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
||||||
|
{
|
||||||
|
auto tmv = it.value();
|
||||||
|
FPGAConfigParam param;
|
||||||
|
from_json(tmv, param);
|
||||||
|
vct_param.push_back(param);
|
||||||
|
}
|
||||||
|
return vct_param;
|
||||||
|
}
|
||||||
|
|
||||||
|
FPGAConfigParam CorrectParam::GetFpgaparam(int dpi,int mode)
|
||||||
|
{
|
||||||
|
FPGAConfigParam param;
|
||||||
|
auto filejson = GetCorrectParams();
|
||||||
|
for (size_t i = 0; i < filejson.size(); i++)
|
||||||
|
{
|
||||||
|
if ((filejson[i].ColorMode == mode) &&
|
||||||
|
(filejson[i].DpiMode == dpi))
|
||||||
|
{
|
||||||
|
param = filejson[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CorrectParam::SaveCorrectParam(FPGAConfigParam& parms)
|
||||||
|
{
|
||||||
|
auto filejson = GetCorrectParams();
|
||||||
|
for (size_t i = 0; i < filejson.size(); i++)
|
||||||
|
{
|
||||||
|
if ((filejson[i].ColorMode == parms.ColorMode) &&
|
||||||
|
(filejson[i].DpiMode == parms.DpiMode))
|
||||||
|
{
|
||||||
|
memcpy(filejson[i].ExposureB, parms.ExposureB, sizeof(parms.ExposureB));
|
||||||
|
memcpy(filejson[i].ExposureF, parms.ExposureF, sizeof(parms.ExposureF));
|
||||||
|
memcpy(filejson[i].GainB, parms.GainB, sizeof(parms.GainB));
|
||||||
|
memcpy(filejson[i].GainF, parms.GainF, sizeof(parms.GainF));
|
||||||
|
memcpy(filejson[i].OffsetB, parms.OffsetB, sizeof(parms.OffsetB));
|
||||||
|
memcpy(filejson[i].OffsetF, parms.OffsetF, sizeof(parms.OffsetF));
|
||||||
|
filejson[i].LutPath = parms.LutPath;
|
||||||
|
filejson[i].TextLutPath = parms.TextLutPath;
|
||||||
|
filejson[i].Flat_BwPath = parms.Flat_BwPath;
|
||||||
|
filejson[i].Flat_WhitePath = parms.Flat_WhitePath;
|
||||||
|
filejson[i].Sp = parms.Sp;
|
||||||
|
filejson[i].HRatio = parms.HRatio;
|
||||||
|
filejson[i].VRatio = parms.VRatio;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
json j = json::array();
|
||||||
|
for (size_t i = 0; i < filejson.size(); i++)
|
||||||
|
{
|
||||||
|
json t_j;
|
||||||
|
to_json(t_j, filejson[i]);
|
||||||
|
j.push_back(t_j);
|
||||||
|
}
|
||||||
|
std::lock_guard<std::mutex> lc(m_lc);
|
||||||
|
ofstream ofs(JSONPATH);
|
||||||
|
ofs << std::setw(4) << j << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CorrectParam::initdefaultpapram()
|
||||||
|
{
|
||||||
|
struct stat buff;
|
||||||
|
if (stat(JSONPATH, &buff) != 0)//不存在
|
||||||
|
{
|
||||||
|
json js = json::array();
|
||||||
|
{
|
||||||
|
FPGAConfigParam param;
|
||||||
|
json t_j;
|
||||||
|
|
||||||
|
//彩色 300 dpi
|
||||||
|
param.ColorMode = 1;//彩色
|
||||||
|
param.DpiMode = 2;//300 dpi
|
||||||
|
param.MaxBright = 200;
|
||||||
|
param.MaxExp = 1470;
|
||||||
|
param.Sp = 1490;
|
||||||
|
param.HRatio = 1065353216;
|
||||||
|
param.VRatio = 1065353216;
|
||||||
|
param.LutPath = LUT300COLORPATH;
|
||||||
|
param.TextLutPath = TEXTLUT300COLORPATH;
|
||||||
|
param.Flat_BwPath = LUT300_COLOR_BLACKPATH;
|
||||||
|
param.Flat_WhitePath = LUT300_COLOR_WHITEPATH;
|
||||||
|
for (size_t i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if(i<3)
|
||||||
|
param.ExposureB[i] = param.ExposureF[i] = 650;//1500
|
||||||
|
param.GainF[i] = param.GainB[i] = 170;
|
||||||
|
param.OffsetF[i] = param.OffsetB[i] = 125;
|
||||||
|
|
||||||
|
}
|
||||||
|
to_json(t_j, param);
|
||||||
|
js.push_back(t_j);
|
||||||
|
|
||||||
|
//灰度 300 dpi
|
||||||
|
param.ColorMode = 0;//灰度
|
||||||
|
param.MaxBright = 200;
|
||||||
|
param.MaxExp = 1780;
|
||||||
|
param.Sp = 4470;
|
||||||
|
param.LutPath = LUT300GRAYPATH;
|
||||||
|
param.TextLutPath = TEXTLUT300GRAYPATH;
|
||||||
|
param.Flat_BwPath = LUT300_GRAY_BLACKPATH;
|
||||||
|
param.Flat_WhitePath = LUT300_GRAY_WHITEPATH;
|
||||||
|
to_json(t_j, param);
|
||||||
|
js.push_back(t_j);
|
||||||
|
|
||||||
|
//彩色 200 dpi
|
||||||
|
param.ColorMode = 1;//彩色
|
||||||
|
param.DpiMode = 1;//200 dpi
|
||||||
|
param.LutPath = LUT200COLORPATH;
|
||||||
|
param.TextLutPath = TEXTLUT200COLORPATH;
|
||||||
|
param.Flat_BwPath = LUT200_COLOR_BLACKPATH;
|
||||||
|
param.Flat_WhitePath = LUT200_COLOR_WHITEPATH;
|
||||||
|
for (size_t i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if(i<3)
|
||||||
|
param.ExposureB[i] = param.ExposureF[i] =600;//1500
|
||||||
|
param.GainF[i] = param.GainB[i] = 170;
|
||||||
|
param.OffsetF[i] = param.OffsetB[i] = 125;
|
||||||
|
}
|
||||||
|
to_json(t_j, param);
|
||||||
|
js.push_back(t_j);
|
||||||
|
|
||||||
|
//灰度 200dpi
|
||||||
|
param.ColorMode = 0;//灰度
|
||||||
|
param.LutPath = LUT200GRAYPATH;
|
||||||
|
param.TextLutPath = TEXTLUT200GRAYPATH;
|
||||||
|
param.Flat_BwPath = LUT200_GRAY_BLACKPATH;
|
||||||
|
param.Flat_WhitePath = LUT200_GRAY_WHITEPATH;
|
||||||
|
to_json(t_j, param);
|
||||||
|
js.push_back(t_j);
|
||||||
|
|
||||||
|
//彩色 600 dpi
|
||||||
|
param.ColorMode = 1;//彩色
|
||||||
|
param.DpiMode = 0x03;//200 dpi
|
||||||
|
param.MaxBright = 180;
|
||||||
|
param.MaxExp = 2680;
|
||||||
|
param.Sp = 2700;
|
||||||
|
param.LutPath = LUT600COLORPATH;
|
||||||
|
param.TextLutPath = TEXTLUT600COLORPATH;
|
||||||
|
param.Flat_BwPath = LUT600_COLOR_BLACKPATH;
|
||||||
|
param.Flat_WhitePath = LUT600_COLOR_WHITEPATH;
|
||||||
|
for (size_t i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if(i<3)
|
||||||
|
param.ExposureB[i] = param.ExposureF[i] = 0x800;//1500
|
||||||
|
param.GainF[i] = param.GainB[i] = 170;
|
||||||
|
param.OffsetF[i] = param.OffsetB[i] = 125;
|
||||||
|
|
||||||
|
}
|
||||||
|
to_json(t_j, param);
|
||||||
|
js.push_back(t_j);
|
||||||
|
|
||||||
|
|
||||||
|
//灰度 600dpi
|
||||||
|
param.ColorMode = 0;//灰度
|
||||||
|
param.DpiMode = 0x03;//600 dpi
|
||||||
|
param.MaxBright = 180;
|
||||||
|
param.MaxExp = 2680;
|
||||||
|
param.Sp = 8135;
|
||||||
|
param.LutPath = LUT600GRAYPATH;
|
||||||
|
param.TextLutPath = TEXTLUT600GRAYPATH;
|
||||||
|
param.Flat_BwPath = LUT600_GRAY_BLACKPATH;
|
||||||
|
param.Flat_WhitePath = LUT600_GRAY_WHITEPATH;
|
||||||
|
to_json(t_j, param);
|
||||||
|
js.push_back(t_j);
|
||||||
|
|
||||||
|
std::ofstream ofs(JSONPATH);
|
||||||
|
ofs << std::setw(4) << js << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CorrectParam::to_json(json& j, FPGAConfigParam& param)
|
||||||
|
{
|
||||||
|
j = json{ {"ExposureF",param.ExposureF},
|
||||||
|
{"GainF",param.GainF},
|
||||||
|
{"OffsetF",param.OffsetF},
|
||||||
|
{"ExposureB",param.ExposureB},
|
||||||
|
{"GainB",param.GainB},
|
||||||
|
{"OffsetB",param.OffsetB},
|
||||||
|
{"DpiMode",param.DpiMode},
|
||||||
|
{"ColorMode",param.ColorMode},
|
||||||
|
{"MaxBright",param.MaxBright},
|
||||||
|
{"MaxExp",param.MaxExp},
|
||||||
|
{"Sp",param.Sp},
|
||||||
|
{"HRatio",param.HRatio},
|
||||||
|
{"VRatio",param.VRatio},
|
||||||
|
{"LutPath",param.LutPath},
|
||||||
|
{"TextLutPath",param.TextLutPath},
|
||||||
|
{"FlatBlackPath",param.Flat_BwPath},
|
||||||
|
{"FlatWhitePath",param.Flat_WhitePath}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CorrectParam::from_json(json& j, FPGAConfigParam& param)
|
||||||
|
{
|
||||||
|
if(j.contains("ExposureF"))
|
||||||
|
j.at("ExposureF").get_to(param.ExposureF);
|
||||||
|
else
|
||||||
|
param.ExposureF[0]=param.ExposureF[1]=param.ExposureF[2]=0x258;
|
||||||
|
|
||||||
|
if(j.contains("GainF"))
|
||||||
|
j.at("GainF").get_to(param.GainF);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0;i< sizeof(param.GainF)/sizeof(param.GainF[0]);i++)
|
||||||
|
{
|
||||||
|
param.GainF[i] = 170;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(j.contains("OffsetF"))
|
||||||
|
j.at("OffsetF").get_to(param.OffsetF);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0;i< sizeof(param.OffsetF)/sizeof(param.OffsetF[0]);i++)
|
||||||
|
{
|
||||||
|
param.OffsetF[i] = 125;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(j.contains("ExposureB"))
|
||||||
|
j.at("ExposureB").get_to(param.ExposureB);
|
||||||
|
else
|
||||||
|
param.ExposureB[0]=param.ExposureB[1]=param.ExposureB[2]=0x258;
|
||||||
|
|
||||||
|
if(j.contains("GainB"))
|
||||||
|
j.at("GainB").get_to(param.GainB);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0;i< sizeof(param.GainB)/sizeof(param.GainB[0]);i++)
|
||||||
|
{
|
||||||
|
param.GainB[i] = 170;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(j.contains("OffsetB"))
|
||||||
|
j.at("OffsetB").get_to(param.OffsetB);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0;i< sizeof(param.OffsetB)/sizeof(param.OffsetB[0]);i++)
|
||||||
|
{
|
||||||
|
param.OffsetB[i] = 125;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(j.contains("DpiMode"))
|
||||||
|
j.at("DpiMode").get_to(param.DpiMode);
|
||||||
|
else
|
||||||
|
param.DpiMode = 1;
|
||||||
|
|
||||||
|
if(j.contains("ColorMode"))
|
||||||
|
j.at("ColorMode").get_to(param.ColorMode);
|
||||||
|
else
|
||||||
|
param.ColorMode = 1;
|
||||||
|
|
||||||
|
if(j.contains("MaxBright"))
|
||||||
|
j.at("MaxBright").get_to(param.MaxBright);
|
||||||
|
else
|
||||||
|
param.MaxBright = 200;
|
||||||
|
|
||||||
|
if(j.contains("MaxExp"))
|
||||||
|
j.at("MaxExp").get_to(param.MaxExp);
|
||||||
|
else
|
||||||
|
param.MaxExp = 0x258;
|
||||||
|
|
||||||
|
if(j.contains("Sp"))
|
||||||
|
j.at("Sp").get_to(param.Sp);
|
||||||
|
else
|
||||||
|
param.Sp = 0x640;
|
||||||
|
|
||||||
|
if(j.contains("HRatio"))
|
||||||
|
j.at("HRatio").get_to(param.HRatio);
|
||||||
|
else
|
||||||
|
param.HRatio = 1065353216;
|
||||||
|
|
||||||
|
if(j.contains("VRatio"))
|
||||||
|
j.at("VRatio").get_to(param.VRatio);
|
||||||
|
else
|
||||||
|
param.VRatio = 1065353216;
|
||||||
|
|
||||||
|
if(j.contains("LutPath"))
|
||||||
|
j.at("LutPath").get_to(param.LutPath);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(param.DpiMode==1)
|
||||||
|
param.LutPath = param.ColorMode == 1 ? LUT200COLORPATH:LUT200GRAYPATH;
|
||||||
|
else if(param.DpiMode==2 )
|
||||||
|
param.LutPath = param.ColorMode == 1 ? LUT300COLORPATH:LUT300GRAYPATH;
|
||||||
|
else if(param.DpiMode==3)
|
||||||
|
param.LutPath = param.ColorMode == 1 ? LUT600COLORPATH:LUT600GRAYPATH;
|
||||||
|
else
|
||||||
|
param.LutPath = "";//未知dpi
|
||||||
|
}
|
||||||
|
|
||||||
|
if(j.contains("TextLutPath"))
|
||||||
|
j.at("TextLutPath").get_to(param.TextLutPath);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(param.DpiMode==1)
|
||||||
|
param.TextLutPath = param.ColorMode == 1 ? TEXTLUT200COLORPATH:TEXTLUT200GRAYPATH;
|
||||||
|
else if(param.DpiMode==2 )
|
||||||
|
param.TextLutPath = param.ColorMode == 1 ? TEXTLUT300COLORPATH:TEXTLUT300GRAYPATH;
|
||||||
|
else if(param.DpiMode==3)
|
||||||
|
param.TextLutPath = param.ColorMode == 1 ? TEXTLUT600COLORPATH:TEXTLUT600GRAYPATH;
|
||||||
|
else
|
||||||
|
param.TextLutPath = "";//未知dpi
|
||||||
|
}
|
||||||
|
|
||||||
|
if(j.contains("FlatBlackPath"))
|
||||||
|
j.at("FlatBlackPath").get_to(param.Flat_BwPath);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(param.DpiMode==1)
|
||||||
|
param.Flat_BwPath = param.ColorMode == 1 ? LUT200_COLOR_BLACKPATH:LUT200_GRAY_BLACKPATH;
|
||||||
|
else if(param.DpiMode==2 )
|
||||||
|
param.Flat_BwPath = param.ColorMode == 1 ? LUT300_COLOR_BLACKPATH:LUT300_GRAY_BLACKPATH;
|
||||||
|
else if(param.DpiMode==3)
|
||||||
|
param.Flat_BwPath = param.ColorMode == 1 ? LUT600_COLOR_BLACKPATH:LUT600_GRAY_BLACKPATH;
|
||||||
|
else
|
||||||
|
param.Flat_BwPath = "";//未知dpi
|
||||||
|
}
|
||||||
|
|
||||||
|
if(j.contains("FlatWhitePath"))
|
||||||
|
j.at("FlatWhitePath").get_to(param.Flat_WhitePath);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(param.DpiMode==1)
|
||||||
|
param.Flat_WhitePath = param.ColorMode == 1 ? LUT200_COLOR_WHITEPATH:LUT200_GRAY_WHITEPATH;
|
||||||
|
else if(param.DpiMode==2 )
|
||||||
|
param.Flat_WhitePath = param.ColorMode == 1 ? LUT300_COLOR_WHITEPATH:LUT300_GRAY_WHITEPATH;
|
||||||
|
else if(param.DpiMode==3)
|
||||||
|
param.Flat_WhitePath = param.ColorMode == 1 ? LUT600_COLOR_WHITEPATH:LUT600_GRAY_WHITEPATH;
|
||||||
|
else
|
||||||
|
param.Flat_WhitePath = "";//未知dpi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
#include "json.hpp"
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include "CameraParam.h"
|
||||||
|
#include "CorrectParam.h"
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
class CorrectParam
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CorrectParam(/* args */);
|
||||||
|
~CorrectParam();
|
||||||
|
FPGAConfigParam GetFpgaparam(int dpi,int mode);
|
||||||
|
void SaveCorrectParam(FPGAConfigParam& parms);
|
||||||
|
private:
|
||||||
|
void initdefaultpapram();
|
||||||
|
std::mutex m_lc;
|
||||||
|
std::vector<FPGAConfigParam> GetCorrectParams();
|
||||||
|
void to_json(json& j, FPGAConfigParam& param);
|
||||||
|
void from_json(json& j, FPGAConfigParam& param);
|
||||||
|
};
|
|
@ -0,0 +1,140 @@
|
||||||
|
#include "CuoZhiMotor.h"
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
CuoZhiMotor::CuoZhiMotor()
|
||||||
|
: Motor(motorPorts_Cuozhi)
|
||||||
|
{
|
||||||
|
auto t_smbtype = smbtype == SMBType::MB_DRV_TMC216 ? MotorConfig::MTBDType::MT_TMC : MotorConfig::MTBDType::MT_DRV;
|
||||||
|
m_cuoparamex = m_mtconfig->GetMotorSpeedParam(false, t_smbtype, 4, 1, 1);
|
||||||
|
speedConfig();
|
||||||
|
mspCuozhiFeeding = {.finalPeriod = 1427500, .Fmin = 2027500, .stepnum = 30, .a = 100, .offset = 4, .finalDelay = 3000};
|
||||||
|
if (smbtype == SMBType::MB_DRV_TMC216)
|
||||||
|
{
|
||||||
|
mspCuozhiFeeding.finalPeriod /= 4;
|
||||||
|
mspCuozhiFeeding.Fmin /= 4;
|
||||||
|
}
|
||||||
|
delays_feeding = speedup_cfg(mspCuozhiFeeding.finalPeriod, mspCuozhiFeeding.Fmin, mspCuozhiFeeding.stepnum, mspCuozhiFeeding.a,
|
||||||
|
mspCuozhiFeeding.offset, mspCuozhiFeeding.finalDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
CuoZhiMotor::~CuoZhiMotor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::pauseWaitForThread()
|
||||||
|
{
|
||||||
|
if (thStart.joinable())
|
||||||
|
{
|
||||||
|
thStart.join();
|
||||||
|
}
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::startAsyn()
|
||||||
|
{
|
||||||
|
if (thStart.joinable())
|
||||||
|
{
|
||||||
|
thStart.join();
|
||||||
|
}
|
||||||
|
thStart = std::thread(&CuoZhiMotor::forward, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::start()
|
||||||
|
{
|
||||||
|
forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::reset()
|
||||||
|
{
|
||||||
|
if (thStart.joinable())
|
||||||
|
{
|
||||||
|
thStart.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
setDirection(1);
|
||||||
|
delays_forward.clear();
|
||||||
|
delays_forward = speedup_cfg(mspCuozhiBackward.finalPeriod,
|
||||||
|
mspCuozhiBackward.Fmin,
|
||||||
|
mspCuozhiBackward.stepnum,
|
||||||
|
mspCuozhiBackward.a,
|
||||||
|
mspCuozhiBackward.offset,
|
||||||
|
mspCuozhiBackward.finalDelay);
|
||||||
|
LOG("finalPeriod=%d Fmin=%d \n", mspCuozhiBackward.finalPeriod, mspCuozhiBackward.Fmin);
|
||||||
|
Motor::start(delays_forward, mspCuozhiBackward);
|
||||||
|
std::random_device rd; // obtain a random number from hardware
|
||||||
|
std::mt19937 gen(rd()); // seed the generator
|
||||||
|
std::uniform_int_distribution<> distr(100, 400); // define the range
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(distr(gen)));
|
||||||
|
stop();
|
||||||
|
delays_backward.clear();
|
||||||
|
delays_backward = speedup_cfg(mspCuozhiBackward.finalPeriod, mspCuozhiBackward.Fmin, mspCuozhiBackward.stepnum, mspCuozhiBackward.a,
|
||||||
|
mspCuozhiBackward.offset, mspCuozhiBackward.finalDelay);
|
||||||
|
setDirection(0);
|
||||||
|
Motor::start(delays_backward, mspCuozhiBackward);
|
||||||
|
if(smbtype==SMBType::MB_DRV_8825)
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
||||||
|
else
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(150));
|
||||||
|
|
||||||
|
stop();
|
||||||
|
speedRecover();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::forward()
|
||||||
|
{
|
||||||
|
setDirection(1);
|
||||||
|
Motor::start(delays_forward, m_cuoparamex.mt_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::backward()
|
||||||
|
{
|
||||||
|
setDirection(0);
|
||||||
|
Motor::start(delays_backward, mspCuozhiBackward);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::feeding()
|
||||||
|
{
|
||||||
|
setDirection(1);
|
||||||
|
Motor::start(delays_feeding, mspCuozhiFeeding);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::speedChange(int speed, int dpi, int colormode) // speed should be in range [0,5] (by ply,at 2019.5.23)
|
||||||
|
{
|
||||||
|
auto t_smbtype = smbtype == SMBType::MB_DRV_8825 ? MotorConfig::MTBDType::MT_DRV : MotorConfig::MTBDType::MT_TMC;
|
||||||
|
m_cuoparamex = m_mtconfig->GetMotorSpeedParam(false, t_smbtype, speed, colormode, dpi);
|
||||||
|
speedConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::speedRecover()
|
||||||
|
{
|
||||||
|
speedConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CuoZhiMotor::speedConfig()
|
||||||
|
{
|
||||||
|
LOG("CuoZhiMotor speed=%d \n dpi=%d \n colormode=%d \n finalPeriod=%d \n Fmin=%d \n a=%.2f \n offset=%.2f \n stepnum=%.2f \n finalDelay=%.2f \n ",
|
||||||
|
m_cuoparamex.speed,
|
||||||
|
m_cuoparamex.dpi,
|
||||||
|
m_cuoparamex.colormode,
|
||||||
|
m_cuoparamex.mt_param.finalPeriod,
|
||||||
|
m_cuoparamex.mt_param.Fmin,
|
||||||
|
m_cuoparamex.mt_param.a,
|
||||||
|
m_cuoparamex.mt_param.offset,
|
||||||
|
m_cuoparamex.mt_param.stepnum,
|
||||||
|
m_cuoparamex.mt_param.finalDelay);
|
||||||
|
|
||||||
|
delays_forward.clear();
|
||||||
|
delays_forward = speedup_cfg(m_cuoparamex.mt_param.finalPeriod, m_cuoparamex.mt_param.Fmin, m_cuoparamex.mt_param.stepnum, m_cuoparamex.mt_param.a,
|
||||||
|
m_cuoparamex.mt_param.offset, m_cuoparamex.mt_param.finalDelay);
|
||||||
|
std::vector<int> vct_speedupdon(delays_forward);
|
||||||
|
|
||||||
|
int size= vct_speedupdon.size();
|
||||||
|
int half_len = vct_speedupdon.size()/3;
|
||||||
|
for (int i = size-1; i > 0; i--)
|
||||||
|
{
|
||||||
|
delays_forward.push_back(vct_speedupdon[i]);
|
||||||
|
}
|
||||||
|
delays_backward.clear();
|
||||||
|
delays_backward = speedup_cfg(mspCuozhiBackward.finalPeriod, mspCuozhiBackward.Fmin, mspCuozhiBackward.stepnum, mspCuozhiBackward.a,
|
||||||
|
mspCuozhiBackward.offset, mspCuozhiBackward.finalDelay);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Motor.h"
|
||||||
|
#include <thread>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class CuoZhiMotor : public Motor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const MotorSpeedParam mspCuozhiBackward= {.finalPeriod = 627500,.Fmin = 1407750,.stepnum = 25,.a=150,.offset=8,.finalDelay=3000,.acceleration_time=0};
|
||||||
|
|
||||||
|
public:
|
||||||
|
CuoZhiMotor();
|
||||||
|
~CuoZhiMotor();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
virtual void start();
|
||||||
|
|
||||||
|
void startAsyn();
|
||||||
|
|
||||||
|
void pauseWaitForThread();
|
||||||
|
|
||||||
|
void backward();
|
||||||
|
|
||||||
|
void feeding();
|
||||||
|
|
||||||
|
void speedChange(int speed, int dpi = 1,int colormode = 1);
|
||||||
|
|
||||||
|
void speedRecover();
|
||||||
|
|
||||||
|
private:
|
||||||
|
MotorSpeedParam mspCuozhiFeeding;
|
||||||
|
std::vector<int> delays_forward;
|
||||||
|
MotorSpeedParamEx m_cuoparamex;
|
||||||
|
std::vector<int> delays_backward;
|
||||||
|
std::vector<int> delays_feeding;
|
||||||
|
std::thread thStart;
|
||||||
|
void forward();
|
||||||
|
void speedConfig();
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "DevUtil.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#define IOEXPORTPATH "/sys/class/gpio/export"
|
||||||
|
#define PWMEXPORTPATH "/sys/class/pwm/pwmchip%d/export"
|
||||||
|
int read_dev_i(std::string path) {
|
||||||
|
int val = -1;
|
||||||
|
std::ifstream ifin(path.c_str());
|
||||||
|
ifin >> val;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string read_dev_s(std::string path) {
|
||||||
|
std::string val;
|
||||||
|
std::ifstream ifin(path.c_str());
|
||||||
|
ifin >> val;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceExport::DeviceExport()
|
||||||
|
{
|
||||||
|
int num = sizeof(ports) / sizeof(ports[0]);
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
write_dev(IOEXPORTPATH, ports[i]);
|
||||||
|
|
||||||
|
num = sizeof(pwms) / sizeof(pwms[0]);
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
write_dev(string_format(PWMEXPORTPATH, pwms[i]), 0);
|
||||||
|
}
|
|
@ -0,0 +1,158 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
|
||||||
|
template<typename ... Args>
|
||||||
|
std::string string_format(const std::string& format, Args ... args) {
|
||||||
|
size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1;
|
||||||
|
std::unique_ptr<char[]> buf(new char[size]);
|
||||||
|
snprintf(buf.get(), size, format.c_str(), args ...);
|
||||||
|
return std::string(buf.get(), buf.get() + size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
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 PIN_PORT_7010
|
||||||
|
{
|
||||||
|
//通道0-------------START
|
||||||
|
SCAN_SENSOR = 0 + 1019, //扫描传感器
|
||||||
|
HAVE_OR_NO_PAPER = 3 + 1019, //有无纸(0:无纸,1:有纸)
|
||||||
|
OPEN_COVER_SENSOR = 4 + 1019, //是否开盖(0:未开盖,1:开盖)
|
||||||
|
|
||||||
|
ULTRASONIC_SENSORS_OUT0 = 18 + 1019,
|
||||||
|
ULTRASONIC_SENSORS_OUT1 = 17 + 1019,
|
||||||
|
ULTRASONIC_SENSORS_ON = 20 + 1019,
|
||||||
|
ULTRASONIC_SENSORS_ADJ = 19 + 1019,
|
||||||
|
//通道0-------------END
|
||||||
|
SENSOR_POWER = 66 + 1019,
|
||||||
|
|
||||||
|
//通道1-------------START
|
||||||
|
BUTTON_1_POWER = 21+1019, //按键1 电源
|
||||||
|
BUTTON_2 = 22+1019, //按键2
|
||||||
|
BUTTON_3 = 23+1019, //按键3
|
||||||
|
LED_0_GREEN = 24+1019,
|
||||||
|
LED_1_WHITE = 25+1019,
|
||||||
|
LED_2_RED = 26+1019,
|
||||||
|
|
||||||
|
//PWM0 电机1-START
|
||||||
|
CUOZHI_PIN_DIR = 54+901, //方向(顺:0)
|
||||||
|
CUOZHI_PIN_ENABEL = 55+901, //使能(有效:0)
|
||||||
|
CUOZHI_PIN_RESET = 56+901, //重启 (1:电机转动,一般默认为1)
|
||||||
|
CUOZHI_PIN_SLEEP = 57+901, //睡眠 (1:电机转动,一般默认为1)
|
||||||
|
//PWM0 电机1-END
|
||||||
|
|
||||||
|
//PWM1 电机2-START
|
||||||
|
ZOUZHI_PIN_DIR = 59+901, //方向(顺:0)
|
||||||
|
ZOUZHI_PIN_ENABEL = 60+901, //使能(有效:0)
|
||||||
|
ZOUZHI_PIN_RESET = 61+901, //重启 (1:电机转动,一般默认为1)
|
||||||
|
ZOUZHI_PIN_SLEEP = 62+901, //睡眠 (1:电机转动,一般默认为1)
|
||||||
|
|
||||||
|
|
||||||
|
//PWM1 电机2-END
|
||||||
|
//通道1-------------END
|
||||||
|
MOTOR_POWER_1 = 64 + 901, //电机1 电源开关
|
||||||
|
MOTOR_POWER_2 = 65 + 901, //电机2 电源开关
|
||||||
|
};
|
||||||
|
enum PORTS
|
||||||
|
{
|
||||||
|
//Start = 171,
|
||||||
|
//Stop = 49,
|
||||||
|
//Power = 5,
|
||||||
|
Fpga_InitN = 7,//GPIO0_A7
|
||||||
|
Fpga_Load = 8,//GPIO0_B7
|
||||||
|
#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
|
||||||
|
//PaperJam = 102,
|
||||||
|
//Double_Paper = 219,// 'GPIO7A3' not doubled:0 ; doubled:1
|
||||||
|
SW_NOR_FLASH = 221,
|
||||||
|
//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,
|
||||||
|
CIS_T_S0=190,
|
||||||
|
CIS_T_S1=191,
|
||||||
|
CIS_T_S2=234,
|
||||||
|
CIS_T_S3=233
|
||||||
|
};
|
||||||
|
|
||||||
|
// class DeviceExport {
|
||||||
|
// public:
|
||||||
|
// DeviceExport();
|
||||||
|
// private:
|
||||||
|
// #ifndef G300
|
||||||
|
// const int ports[42] = { 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, PaperJam,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, SW_NOR_FLASH,CIS_T_S0,CIS_T_S1,CIS_T_S2,CIS_T_S3};
|
||||||
|
// #else
|
||||||
|
// const int ports[37] = { 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, PaperJam, 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,Fpga_InitN };
|
||||||
|
// #endif
|
||||||
|
// const int pwms[2] = { 2, 3 };
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceExport
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DeviceExport();
|
||||||
|
private:
|
||||||
|
const int ports[14] = { MOTOR_POWER_1, CUOZHI_PIN_RESET, CUOZHI_PIN_SLEEP,CUOZHI_PIN_ENABEL, CUOZHI_PIN_DIR,
|
||||||
|
MOTOR_POWER_2, ZOUZHI_PIN_RESET, ZOUZHI_PIN_SLEEP,ZOUZHI_PIN_ENABEL, ZOUZHI_PIN_DIR,
|
||||||
|
SCAN_SENSOR,HAVE_OR_NO_PAPER, OPEN_COVER_SENSOR,};
|
||||||
|
|
||||||
|
const int pwms[4] = { 0, 1 ,2};
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,633 @@
|
||||||
|
//
|
||||||
|
// Created by Nick on 2019/4/7.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "FpgaComm.h"
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#define LOG_TAG "FpgaComm"
|
||||||
|
#define LOGD(...) ((void)printf(__VA_ARGS__))
|
||||||
|
|
||||||
|
int FpgaComm::read(int addr)
|
||||||
|
{
|
||||||
|
unsigned char *pdata = bufRecv;
|
||||||
|
pdata[0] = 0x03;
|
||||||
|
pdata[1] = (unsigned char)addr;
|
||||||
|
m_serial.Write(bufRecv, 2);
|
||||||
|
if (m_serial.Read(bufRecv, 5, 300))
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
unsigned char *pdata = (unsigned char *)(&ret);
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
pdata[i] = bufRecv[4 - i];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::write(int addr, int data)
|
||||||
|
{
|
||||||
|
unsigned char *pdata = bufSend;
|
||||||
|
pdata[0] = 0x83;
|
||||||
|
pdata[1] = (unsigned char)addr;
|
||||||
|
unsigned char *idata = (unsigned char *)&data;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
pdata[6 - i] = idata[i];
|
||||||
|
}
|
||||||
|
m_serial.Write(bufSend, sizeof(bufSend));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::updateRegs(int addr)
|
||||||
|
{
|
||||||
|
write(addr, fpgaParams.regs[addr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setFrameHeight(int height)
|
||||||
|
{
|
||||||
|
fpgaParams.params.frame.height = height;
|
||||||
|
write(0x00, fpgaParams.regs[0x00]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getFrameHeight()
|
||||||
|
{
|
||||||
|
// fpgaParams.params.frame.height = height;
|
||||||
|
int reg0v = read(0x00);
|
||||||
|
FrameFpga *frameinfo = (FrameFpga *)®0v;
|
||||||
|
return frameinfo->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getAutoFrameHeight()
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
unsigned int reg8 = 0;
|
||||||
|
reg8 = read(0x08);
|
||||||
|
val = read(14);
|
||||||
|
int regv = val;
|
||||||
|
val &= 0x0000ffff;
|
||||||
|
write(0x8, reg8 & 0xfffffff7);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
// val = read(14);
|
||||||
|
// regv = val;
|
||||||
|
// val &= 0x0000ffff;
|
||||||
|
// reg8 = read(0x8);
|
||||||
|
// LOG("TWO height = %d reg[14] = %d \n", val, regv);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
write(0x8, reg8 | 0x8);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setFrameNum(int num)
|
||||||
|
{
|
||||||
|
fpgaParams.params.frame.num = num;
|
||||||
|
write(0x00, fpgaParams.regs[0x00]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::enableLed(bool bEnable)
|
||||||
|
{
|
||||||
|
fpgaParams.params.AledR.user_define.led_sample.ledEnable = bEnable;
|
||||||
|
write(0x05, fpgaParams.regs[0x05]);
|
||||||
|
#ifdef HAS_UV
|
||||||
|
fpgaParams.params.BledR.user_define.led_sample.ledEnable = bEnable;
|
||||||
|
write(0x08, fpgaParams.regs[0x08]);
|
||||||
|
#else
|
||||||
|
fpgaParams.params.BledR.user_define.led_sample.ledEnable = 0;
|
||||||
|
write(0x08, fpgaParams.regs[0x08]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::enableUV(bool enable)
|
||||||
|
{
|
||||||
|
#ifdef HAS_UV
|
||||||
|
isUVEnable = enable;
|
||||||
|
fpgaParams.params.BledR.user_define.led_sample.ledEnable = isUVEnable;
|
||||||
|
write(0x08, fpgaParams.regs[0x08]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::capture()
|
||||||
|
{ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʲô<CAB2>أ<EFBFBD>
|
||||||
|
fpgaParams.params.cmd.cmd = 0;
|
||||||
|
write(0x02, fpgaParams.regs[0x02]);
|
||||||
|
fpgaParams.params.cmd.cmd = 1;
|
||||||
|
write(0x02, fpgaParams.regs[0x02]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getRegs(int addr)
|
||||||
|
{
|
||||||
|
return fpgaParams.regs[addr];
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setRegs(int addr, int value)
|
||||||
|
{
|
||||||
|
fpgaParams.regs[addr] = value;
|
||||||
|
write(addr, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
FpgaComm::FpgaComm() : fanGpio(FAN_PORT) // <20><>ʼ<EFBFBD><CABC>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ȡ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||||
|
{
|
||||||
|
m_serial.Open(com.c_str(), bauds);
|
||||||
|
// for(int i = 0; i < MAX_REGS; i++){
|
||||||
|
// fpgaParams.regs[i] = read(i);
|
||||||
|
// LOG("reg[%d] = 0x%08x \n", i, fpgaParams.regs[i]);
|
||||||
|
// }
|
||||||
|
fpgaParams.params.AledR.user_define.led_sample.sample = 256;
|
||||||
|
updateRegs(0x05);
|
||||||
|
|
||||||
|
enableLed(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::updateRegs()
|
||||||
|
{
|
||||||
|
for (int i = 0x05; i < MAX_REGS; i++)
|
||||||
|
{
|
||||||
|
updateRegs(i);
|
||||||
|
}
|
||||||
|
fpgaParams.params.AledR.user_define.led_sample.sample = 256;
|
||||||
|
updateRegs(0x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setAGain(int indexGain, int value)
|
||||||
|
{
|
||||||
|
AdGain adGain;
|
||||||
|
adGain.value = value;
|
||||||
|
indexGain++;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_addr = indexGain * 2;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_addr = fpgaParams.params.Aad.bits.ad0_addr + 1;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_value = adGain.gain_value.gain_low8;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_value = adGain.gain_value.gain_hight;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_rw = 0;
|
||||||
|
updateRegs(0x04);
|
||||||
|
fpgaParams.params.mode.adcA = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcA = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::getAGain(int indexGain, int &Avalue, int &Bvalue)
|
||||||
|
{
|
||||||
|
AdGain adGain;
|
||||||
|
CisAdGain adgain;
|
||||||
|
// adGain.value = value;
|
||||||
|
indexGain++;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_addr = indexGain * 2;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_addr = fpgaParams.params.Aad.bits.ad0_addr + 1;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_value = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_value = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_rw = 0;
|
||||||
|
updateRegs(0x04);
|
||||||
|
fpgaParams.params.mode.adcA = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcA = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
auto ret = read(0x03);
|
||||||
|
adgain.value = ret;
|
||||||
|
Avalue = adgain.bits.ad0_value;
|
||||||
|
Bvalue = adgain.bits.ad1_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setBGain(int indexGain, int value)
|
||||||
|
{
|
||||||
|
AdGain adGain;
|
||||||
|
adGain.value = value;
|
||||||
|
indexGain++;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_addr = indexGain * 2;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_addr = indexGain * 2 + 1;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_value = adGain.gain_value.gain_low8;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_value = adGain.gain_value.gain_hight;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_rw = 0;
|
||||||
|
updateRegs(0x07);
|
||||||
|
fpgaParams.params.mode.adcB = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcB = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::getBGain(int indexGain, int &Avalue, int &Bvalue)
|
||||||
|
{
|
||||||
|
AdGain adGain;
|
||||||
|
CisAdGain adgain;
|
||||||
|
// adGain.value = value;
|
||||||
|
indexGain++;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_addr = indexGain * 2;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_addr = indexGain * 2 + 1;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_value = adGain.gain_value.gain_low8;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_value = adGain.gain_value.gain_hight;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_rw = 1;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_rw = 1;
|
||||||
|
updateRegs(0x07);
|
||||||
|
fpgaParams.params.mode.adcB = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcB = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
auto ret = read(0x03);
|
||||||
|
adgain.value = ret;
|
||||||
|
Avalue = adgain.bits.ad0_value;
|
||||||
|
Bvalue = adgain.bits.ad1_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setAOffset(int indexOffset, int value)
|
||||||
|
{
|
||||||
|
fpgaParams.params.Aad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_addr = indexOffset + 0x0e;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_addr = 0x14;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_value = 0x50;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_value = value;
|
||||||
|
updateRegs(0x04);
|
||||||
|
fpgaParams.params.mode.adcA = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcA = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::getAOffset(int indexGain, int &Avalue, int &Bvalue)
|
||||||
|
{
|
||||||
|
fpgaParams.params.Aad.bits.ad0_rw = 1;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_rw = 1;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_addr = indexGain + 0x0e;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_addr = 0x14;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_value = 0x50;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_value = 0;
|
||||||
|
updateRegs(0x04);
|
||||||
|
fpgaParams.params.mode.adcA = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcA = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
CisAdGain adgain;
|
||||||
|
auto ret = read(0x03);
|
||||||
|
adgain.value = ret;
|
||||||
|
Avalue = adgain.bits.ad0_value;
|
||||||
|
Bvalue = adgain.bits.ad1_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setBOffset(int indexOffset, int value)
|
||||||
|
{
|
||||||
|
fpgaParams.params.Bad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_rw = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_addr = indexOffset + 0x0e;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_addr = 0x14;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_value = 0x50;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_value = value;
|
||||||
|
updateRegs(0x07);
|
||||||
|
fpgaParams.params.mode.adcB = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcB = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::getBOffset(int indexGain, int &Avalue, int &Bvalue)
|
||||||
|
{
|
||||||
|
fpgaParams.params.Bad.bits.ad0_rw = 1;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_rw = 1;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_addr = indexGain + 0x0e;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_addr = 0x14;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_value = 0x50;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_value = 0;
|
||||||
|
updateRegs(0x07);
|
||||||
|
fpgaParams.params.mode.adcB = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcB = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
CisAdGain adgain;
|
||||||
|
auto ret = read(0x03);
|
||||||
|
adgain.value = ret;
|
||||||
|
Avalue = adgain.bits.ad0_value;
|
||||||
|
Bvalue = adgain.bits.ad1_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setAExposureR(int value)
|
||||||
|
{
|
||||||
|
fpgaParams.params.AledR.ledR = value;
|
||||||
|
updateRegs(0x05);
|
||||||
|
fpgaParams.regs[0x05] = read(0x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setAExposureG(int value)
|
||||||
|
{
|
||||||
|
fpgaParams.params.AledGB.bits.ledG = value;
|
||||||
|
updateRegs(0x06);
|
||||||
|
fpgaParams.regs[0x06] = read(0x06);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setAExposureB(int value)
|
||||||
|
{
|
||||||
|
fpgaParams.params.AledGB.bits.ledB = value;
|
||||||
|
updateRegs(0x06);
|
||||||
|
fpgaParams.regs[0x06] = read(0x06);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setAExposureUV(int value)
|
||||||
|
{
|
||||||
|
#ifdef HAS_UV
|
||||||
|
fpgaParams.params.UVLed.bits.ledASide = value;
|
||||||
|
updateRegs(0x0d);
|
||||||
|
fpgaParams.regs[0x0d] = read(0x0d);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setBExposureR(int value)
|
||||||
|
{
|
||||||
|
fpgaParams.params.BledR.ledR = value;
|
||||||
|
updateRegs(0x08);
|
||||||
|
fpgaParams.regs[0x08] = read(0x08);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setBExposureG(int value)
|
||||||
|
{
|
||||||
|
fpgaParams.params.BledGB.bits.ledG = value;
|
||||||
|
updateRegs(0x09);
|
||||||
|
fpgaParams.regs[0x09] = read(0x09);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setBExposureB(int value)
|
||||||
|
{
|
||||||
|
fpgaParams.params.BledGB.bits.ledB = value;
|
||||||
|
updateRegs(0x09);
|
||||||
|
fpgaParams.regs[0x09] = read(0x09);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setBExpousreUV(int value)
|
||||||
|
{
|
||||||
|
#ifdef HAS_UV
|
||||||
|
fpgaParams.params.UVLed.bits.ledBSide = value;
|
||||||
|
updateRegs(0x0d);
|
||||||
|
fpgaParams.regs[0x0d] = read(0x0d);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setEnTestCol(bool en)
|
||||||
|
{
|
||||||
|
fpgaParams.params.AledR.user_define.led_sample.en_test_color = en ? 1 : 0;
|
||||||
|
updateRegs(0x05);
|
||||||
|
fpgaParams.regs[0x05] = read(0x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setEnTestBit(bool en)
|
||||||
|
{
|
||||||
|
fpgaParams.params.AledR.user_define.led_sample.en_test = en ? 1 : 0;
|
||||||
|
updateRegs(0x05);
|
||||||
|
fpgaParams.regs[0x05] = read(0x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setFanMode(int mode)
|
||||||
|
{
|
||||||
|
fanGpio.setValue(mode == 3 ? Gpio::Low : Gpio::High);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setSp(int value)
|
||||||
|
{
|
||||||
|
setRegs(0x01, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getSp()
|
||||||
|
{
|
||||||
|
return fpgaParams.params.mode.sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setColorMode(int mode)
|
||||||
|
{
|
||||||
|
fpgaParams.params.mode.colorMode = mode;
|
||||||
|
updateRegs(0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getColorMode()
|
||||||
|
{
|
||||||
|
return fpgaParams.params.mode.colorMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setSample(int sample)
|
||||||
|
{
|
||||||
|
fpgaParams.params.mode.sample = sample;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.AledR.user_define.led_sample.sample = sample;
|
||||||
|
updateRegs(0x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::EnableTest(bool bTest)
|
||||||
|
{
|
||||||
|
fpgaParams.params.mode.selftest = bTest;
|
||||||
|
updateRegs(0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::IsTest()
|
||||||
|
{
|
||||||
|
return fpgaParams.params.mode.selftest;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getSample()
|
||||||
|
{
|
||||||
|
return fpgaParams.params.mode.sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setDpi(int dpi)
|
||||||
|
{
|
||||||
|
fpgaParams.params.mode.dpi = dpi;
|
||||||
|
updateRegs(0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getDpi()
|
||||||
|
{
|
||||||
|
return fpgaParams.params.mode.dpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setSample(int sampleFront, int sampleBack)
|
||||||
|
{
|
||||||
|
fpgaParams.params.mode.sample = sampleFront;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.AledR.user_define.led_sample.sample = sampleBack;
|
||||||
|
updateRegs(0x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 20190626 YHP autoTrig function
|
||||||
|
void FpgaComm::setTrigMode(bool isArmMode)
|
||||||
|
{
|
||||||
|
int tmp = read(0x0b);
|
||||||
|
if (!isArmMode)
|
||||||
|
{ // default value+ ARM MODE,bit27 =0;
|
||||||
|
fpgaParams.params.TrigMode = tmp & 0XFBFFFFFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpgaParams.params.TrigMode = tmp | (1 << 26);
|
||||||
|
}
|
||||||
|
updateRegs(0x0b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void FpgaComm::setDelayTime(int value) {
|
||||||
|
// // fpgaParams.params.DelayTime = value;
|
||||||
|
// // updateRegs(0x0C);
|
||||||
|
// }
|
||||||
|
void FpgaComm::setFrame_interval_min(int min)
|
||||||
|
{
|
||||||
|
fpgaParams.params.FrameInterval.Frame_Interval_min = min;
|
||||||
|
fpgaParams.params.FrameInterval.reversed = 0;
|
||||||
|
updateRegs(0xc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getFrame_interval_min()
|
||||||
|
{
|
||||||
|
fpgaParams.params.FrameInterval.reversed = 0;
|
||||||
|
auto value = read(0x0c);
|
||||||
|
fpgaParams.params.FrameInterval = *(CisFrameInterval *)&value;
|
||||||
|
return fpgaParams.params.FrameInterval.Frame_Interval_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setFrame_interval_max(int max)
|
||||||
|
{
|
||||||
|
fpgaParams.params.FrameInterval.Frame_Interval_max = max;
|
||||||
|
fpgaParams.params.FrameInterval.reversed = 0;
|
||||||
|
updateRegs(0xc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getFrame_interval_max()
|
||||||
|
{
|
||||||
|
fpgaParams.params.FrameInterval.reversed = 0;
|
||||||
|
auto value = read(0x0c);
|
||||||
|
fpgaParams.params.FrameInterval = *(CisFrameInterval *)&value;
|
||||||
|
return fpgaParams.params.FrameInterval.Frame_Interval_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD>¼Ĵ<C2BC><C4B4><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||||
|
void FpgaComm::update()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_REGS; i++)
|
||||||
|
{
|
||||||
|
fpgaParams.regs[i] = read(i);
|
||||||
|
LOG("reg[%d] = 0x%08x \n", i, fpgaParams.regs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::enableJamCheck(bool b)
|
||||||
|
{
|
||||||
|
// fpgaParams.params.BledR.user_define.led_sample.jamEnable = b;
|
||||||
|
// updateRegs(0x08);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::resetADC()
|
||||||
|
{
|
||||||
|
fpgaParams.params.Aad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_addr = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_value = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_addr = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_value = 0;
|
||||||
|
updateRegs(0x04);
|
||||||
|
fpgaParams.params.mode.adcA = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcA = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.Bad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_addr = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_value = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_rw = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_addr = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_value = 0;
|
||||||
|
updateRegs(0x07);
|
||||||
|
fpgaParams.params.mode.adcB = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcB = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
fpgaParams.params.Aad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_addr = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_value = 7;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_addr = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_value = 7;
|
||||||
|
updateRegs(0x04);
|
||||||
|
fpgaParams.params.mode.adcA = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcA = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.Bad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_addr = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_value = 7;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_rw = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_addr = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_value = 7;
|
||||||
|
updateRegs(0x07);
|
||||||
|
fpgaParams.params.mode.adcB = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcB = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.Aad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_addr = 1;
|
||||||
|
fpgaParams.params.Aad.bits.ad0_value = 0x50;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_rw = 0;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_addr = 1;
|
||||||
|
fpgaParams.params.Aad.bits.ad1_value = 0x50;
|
||||||
|
updateRegs(0x04);
|
||||||
|
fpgaParams.params.mode.adcA = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcA = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.Bad.bits.ad0_rw = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_addr = 1;
|
||||||
|
fpgaParams.params.Bad.bits.ad0_value = 0x50;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_rw = 0;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_addr = 1;
|
||||||
|
fpgaParams.params.Bad.bits.ad1_value = 0x50;
|
||||||
|
updateRegs(0x07);
|
||||||
|
fpgaParams.params.mode.adcB = 1;
|
||||||
|
updateRegs(0x01);
|
||||||
|
fpgaParams.params.mode.adcB = 0;
|
||||||
|
updateRegs(0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::setVsp(unsigned int Aside, unsigned int BSide)
|
||||||
|
{
|
||||||
|
// auto ret = read(13);
|
||||||
|
CISVSP vsp; // = *(CISVSP*)&ret;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int FpgaComm::getFrame_counter_val()
|
||||||
|
{
|
||||||
|
int crt_frame_count=0;
|
||||||
|
unsigned int reg8 = 0;
|
||||||
|
|
||||||
|
reg8 = read(8);
|
||||||
|
//write(8,reg8 & 0x8);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
write(8, reg8 & 0xfffffff7);//off stop snap
|
||||||
|
reg8 = read(8);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
crt_frame_count = read(0x10);
|
||||||
|
|
||||||
|
if(crt_frame_count <= 0)//读取失败或帧数为0的情况下,多读几次
|
||||||
|
{
|
||||||
|
for(int i = 0;i<3;i++)
|
||||||
|
{
|
||||||
|
crt_frame_count = read(0x10);
|
||||||
|
printf("try %d times read frame count,frame_count = %d \n",i,crt_frame_count);
|
||||||
|
if(crt_frame_count > 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write(8, reg8 | 0x8);// on reset counter
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||||
|
//printf("TWO height reg[14] = %d reg[16] = %d \n", read(14) & 0xffff,read(16));
|
||||||
|
return crt_frame_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FpgaComm::getFrameNum(){
|
||||||
|
return fpgaParams.params.frame.num;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FpgaComm::set_cis_type(bool isA3_CIS)
|
||||||
|
{
|
||||||
|
fpgaParams.params.AledR.user_define.led_sample.cis_type = isA3_CIS?1:0;
|
||||||
|
}
|
|
@ -0,0 +1,284 @@
|
||||||
|
//
|
||||||
|
// Created by Nick on 2019/4/7.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HGSCANSERVICE_FPGACOMM_H
|
||||||
|
#define HGSCANSERVICE_FPGACOMM_H
|
||||||
|
|
||||||
|
#include "serialib.h"
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <cstring>
|
||||||
|
#include "Gpio.h"
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
//#define HAS_UV
|
||||||
|
|
||||||
|
#ifdef HAS_UV
|
||||||
|
#define MAX_REGS 0x0e
|
||||||
|
#else
|
||||||
|
#define MAX_REGS 0x0d
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct Frame_FPGA
|
||||||
|
{
|
||||||
|
unsigned int height:16;
|
||||||
|
unsigned int num : 16;
|
||||||
|
} FrameFpga;
|
||||||
|
|
||||||
|
typedef struct Mode_FPGA
|
||||||
|
{
|
||||||
|
unsigned short int colorMode : 1;
|
||||||
|
unsigned short int dpi : 2;
|
||||||
|
unsigned short int led : 1;
|
||||||
|
unsigned short sample : 9;
|
||||||
|
unsigned short int adcA : 1;
|
||||||
|
unsigned short int adcB : 1;
|
||||||
|
unsigned short int selftest : 1;
|
||||||
|
unsigned short int sp;
|
||||||
|
} ModeFpga;
|
||||||
|
|
||||||
|
typedef struct CMD_FPGA
|
||||||
|
{
|
||||||
|
unsigned int cmd : 1; //start : 1 , stop : 0
|
||||||
|
unsigned int reserved : 31;
|
||||||
|
} CmdFpga;
|
||||||
|
|
||||||
|
typedef struct STATUS_FPGA
|
||||||
|
{
|
||||||
|
unsigned int status : 1; //start : 1 , stop : 0
|
||||||
|
unsigned int reserved : 31;
|
||||||
|
} StatusFpga;
|
||||||
|
|
||||||
|
typedef union Ad_Gain
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short int gain_low8 : 8;
|
||||||
|
unsigned short int gain_hight : 1;
|
||||||
|
} gain_value;
|
||||||
|
unsigned short int value;
|
||||||
|
} AdGain;
|
||||||
|
|
||||||
|
typedef union CIS_AD_Gain
|
||||||
|
{
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short int ad0_value : 8; //!< 数据位
|
||||||
|
unsigned short int ad0_reserved : 2; //!< 保留位
|
||||||
|
unsigned short int ad0_addr : 5; //!< 寄存器地址
|
||||||
|
unsigned short int ad0_rw : 1; //!< 读写位 1:读, 0:写
|
||||||
|
unsigned short int ad1_value : 8; //!< 数据位
|
||||||
|
unsigned short int ad1_reserved : 2; //!< 保留位
|
||||||
|
unsigned short int ad1_addr : 5; //!< 寄存器地址
|
||||||
|
unsigned short int ad1_rw : 1; //!< 读写位 1:读, 0:写;
|
||||||
|
} bits;
|
||||||
|
int value;
|
||||||
|
} CisAdGain;
|
||||||
|
|
||||||
|
typedef struct CIS_LED_RF {
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short int ledEnable : 1;
|
||||||
|
unsigned short int fanMode : 2;
|
||||||
|
unsigned short int jamEnable : 1;
|
||||||
|
unsigned short int sample : 9;
|
||||||
|
} led_sample;
|
||||||
|
unsigned short int reserved;
|
||||||
|
} user_define;
|
||||||
|
unsigned short int ledR;
|
||||||
|
}CisLedRF;
|
||||||
|
|
||||||
|
typedef struct CIS_LED_R
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short int ledEnable : 1;
|
||||||
|
unsigned short int sample : 9;
|
||||||
|
unsigned short int en_test_color :1;
|
||||||
|
unsigned short int en_test : 1;
|
||||||
|
unsigned short int cis_type : 1 ;
|
||||||
|
} led_sample;
|
||||||
|
unsigned short int reserved;
|
||||||
|
} user_define;
|
||||||
|
unsigned short int ledR;
|
||||||
|
} CisLedR;
|
||||||
|
|
||||||
|
typedef union CIS_LED_GB
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short int ledG;
|
||||||
|
unsigned short int ledB;
|
||||||
|
} bits;
|
||||||
|
int value;
|
||||||
|
} CisLedGB;
|
||||||
|
|
||||||
|
typedef union CIS_LED_UV
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short int ledASide;
|
||||||
|
unsigned short int ledBSide;
|
||||||
|
} bits;
|
||||||
|
int value;
|
||||||
|
} CisLedUv;
|
||||||
|
|
||||||
|
typedef union CIS_VSP
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int ASide_VSP:9;
|
||||||
|
unsigned int BSide_VSP:9;
|
||||||
|
unsigned int reserved : 14;
|
||||||
|
} bits;
|
||||||
|
int value;
|
||||||
|
} CISVSP;
|
||||||
|
|
||||||
|
typedef struct CIS_FRAME_INTERVAL
|
||||||
|
{
|
||||||
|
unsigned short Frame_Interval_min;
|
||||||
|
unsigned short Frame_Interval_max:13;
|
||||||
|
unsigned short reversed:3;
|
||||||
|
}CisFrameInterval;
|
||||||
|
|
||||||
|
typedef union Fpga_Params
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
FrameFpga frame; //0x00
|
||||||
|
ModeFpga mode; //0x01
|
||||||
|
CmdFpga cmd; //0x02
|
||||||
|
StatusFpga status; //0x03
|
||||||
|
CisAdGain Aad; //0x04
|
||||||
|
CisLedR AledR; //0x05
|
||||||
|
CisLedGB AledGB; //0x06
|
||||||
|
CisAdGain Bad; //0x07
|
||||||
|
#ifndef G300
|
||||||
|
CisLedRF BledR; //0x08
|
||||||
|
#else
|
||||||
|
CisLedR BledR; //0x08
|
||||||
|
#endif
|
||||||
|
CisLedGB BledGB; //0x09
|
||||||
|
unsigned int ExpIncr; //0x0a
|
||||||
|
unsigned int TrigMode; //0x0b
|
||||||
|
CisFrameInterval FrameInterval; //0x0c
|
||||||
|
CisLedUv UVLed; //0x0d
|
||||||
|
unsigned int reversed;//0x0e
|
||||||
|
unsigned int fpgaversion;//0x0f
|
||||||
|
unsigned int ConFrameCount;//多帧计数
|
||||||
|
} params;
|
||||||
|
int regs[17];
|
||||||
|
} FpgaParams;
|
||||||
|
|
||||||
|
#define FAN_PORT 59
|
||||||
|
class FpgaComm
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FpgaComm();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void setRegs(int addr, int value);
|
||||||
|
|
||||||
|
int getRegs(int addr);
|
||||||
|
|
||||||
|
void setFrameHeight(int height);
|
||||||
|
|
||||||
|
int getFrameHeight();
|
||||||
|
|
||||||
|
int getAutoFrameHeight();
|
||||||
|
|
||||||
|
void setFrameNum(int num);
|
||||||
|
|
||||||
|
void enableLed(bool bEnable);
|
||||||
|
|
||||||
|
void enableUV(bool enable);
|
||||||
|
|
||||||
|
void capture();
|
||||||
|
|
||||||
|
void updateRegs();
|
||||||
|
|
||||||
|
void setAGain(int indexGain, int value);
|
||||||
|
void getAGain(int indexGain, int &Avalue, int &Bvalue);
|
||||||
|
|
||||||
|
void setBGain(int indexGain, int value);
|
||||||
|
void getBGain(int indexGain, int &Avalue, int &Bvalue);
|
||||||
|
|
||||||
|
void setAOffset(int indexOffset, int value);
|
||||||
|
void getAOffset(int indexGain, int &Avalue, int &Bvalue);
|
||||||
|
|
||||||
|
void setBOffset(int indexOffset, int value);
|
||||||
|
void getBOffset(int indexGain, int &Avalue, int &Bvalue);
|
||||||
|
|
||||||
|
void setAExposureR(int value);
|
||||||
|
void setAExposureG(int value);
|
||||||
|
void setAExposureB(int value);
|
||||||
|
void setAExposureUV(int value);
|
||||||
|
|
||||||
|
void setBExposureR(int value);
|
||||||
|
void setBExposureG(int value);
|
||||||
|
void setBExposureB(int value);
|
||||||
|
void setBExpousreUV(int value);
|
||||||
|
|
||||||
|
void setEnTestCol(bool en);
|
||||||
|
void setEnTestBit(bool en);
|
||||||
|
|
||||||
|
void setFanMode(int mode);
|
||||||
|
|
||||||
|
void setSp(int value);
|
||||||
|
int getSp();
|
||||||
|
void setSample(int sampleFront,int sampleBack);
|
||||||
|
void EnableTest(bool bTest);
|
||||||
|
int IsTest();
|
||||||
|
|
||||||
|
void setColorMode(int mode);
|
||||||
|
int getColorMode();
|
||||||
|
|
||||||
|
void setDpi(int dpi);
|
||||||
|
int getDpi();
|
||||||
|
|
||||||
|
void setSample(int sample);
|
||||||
|
int getSample();
|
||||||
|
|
||||||
|
int read(int addr);
|
||||||
|
|
||||||
|
//20190626 YHP autoTrig function
|
||||||
|
void setFrame_interval_min(int min);
|
||||||
|
int getFrame_interval_min();
|
||||||
|
void setFrame_interval_max(int max);
|
||||||
|
int getFrame_interval_max();
|
||||||
|
//void setDelayTime(int value);
|
||||||
|
void setTrigMode(bool isArmMode);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
void enableJamCheck(bool b);
|
||||||
|
|
||||||
|
void resetADC();
|
||||||
|
|
||||||
|
void setVsp(unsigned int Aside,unsigned int BSide);
|
||||||
|
|
||||||
|
unsigned int getFrame_counter_val();
|
||||||
|
|
||||||
|
int getFrameNum();
|
||||||
|
void set_cis_type(bool isA3_CIS);
|
||||||
|
private:
|
||||||
|
const std::string com = "/dev/ttyS3";
|
||||||
|
const unsigned int bauds = 921600;
|
||||||
|
unsigned char bufSend[7];
|
||||||
|
unsigned char bufRecv[5];
|
||||||
|
serialib m_serial;
|
||||||
|
FpgaParams fpgaParams;
|
||||||
|
bool isUVEnable = false;
|
||||||
|
Gpio fanGpio;
|
||||||
|
void updateRegs(int addr);
|
||||||
|
|
||||||
|
void write(int addr, int data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //HGSCANSERVICE_FPGACOMM_H
|
|
@ -0,0 +1,339 @@
|
||||||
|
#include "FsmState.h"
|
||||||
|
#include "Scanner.h"
|
||||||
|
|
||||||
|
|
||||||
|
Scanner *FsmState::scanner = NULL;
|
||||||
|
|
||||||
|
FsmState::FsmState()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FsmState::~FsmState()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::shared_ptr<FsmState>> FsmStateManager::fsmStates;
|
||||||
|
|
||||||
|
void StandbyState::initial()
|
||||||
|
{
|
||||||
|
LOG("StandbyState \n");
|
||||||
|
typeName = "StandbyState";
|
||||||
|
scanner->getPanelLeds().setStatus(LedStatus::Ready);
|
||||||
|
doReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
FsmState *StandbyState::on_event(ScanEvent event)
|
||||||
|
{
|
||||||
|
LOG("StandbyState on_event %d \n", event);
|
||||||
|
if (event == S_EVT_COVER_OPENED)
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<CoverOpenState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_JAM_OUT)
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<ErrorJamState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_PAPER_STANDBY)
|
||||||
|
{
|
||||||
|
if (scanner->getSensor().isPaperStandby())
|
||||||
|
{
|
||||||
|
LOG("StandbyState on_event : %s \n", "true");
|
||||||
|
return FsmStateManagerEx<PaperReadyState>::GetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_START_SCAN)
|
||||||
|
{
|
||||||
|
scanner->getPanelLeds().setStatus(LedStatus::NoPaper);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1200));
|
||||||
|
scanner->getPanelLeds().setStatus(LedStatus::Ready);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandbyState::doReset()
|
||||||
|
{
|
||||||
|
if (!scanner->isRested)
|
||||||
|
scanner->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoverOpenState::initial()
|
||||||
|
{
|
||||||
|
LOG("CoverOpenState \n");
|
||||||
|
typeName = "CoverOpenState";
|
||||||
|
scanner->getPanelLeds().setStatus(LedStatus::CoverOpen);
|
||||||
|
}
|
||||||
|
|
||||||
|
FsmState *CoverOpenState::on_event(ScanEvent event)
|
||||||
|
{
|
||||||
|
LOG("CoverOpenState on_event %d \n", event);
|
||||||
|
if (event == S_EVT_COVER_CLOSED)
|
||||||
|
{
|
||||||
|
if (!scanner->getSensor().isPaperAtScan())
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
scanner->reset();
|
||||||
|
return FsmStateManagerEx<InitState>::GetState();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<ErrorJamState>::GetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_CLEAR_ERR)
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<InitState>::GetState();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitState::InitState()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FsmState *InitState::on_event(ScanEvent event)
|
||||||
|
{
|
||||||
|
LOG("InitState on_event %d \n", event);
|
||||||
|
if (!(scanner->getSensor().isCoverClosed()))
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<CoverOpenState>::GetState();
|
||||||
|
}
|
||||||
|
else if (scanner->getSensor().isPaperStandby())
|
||||||
|
{
|
||||||
|
LOG("------------------有纸\r\n");
|
||||||
|
return FsmStateManagerEx<PaperReadyState>::GetState();
|
||||||
|
}
|
||||||
|
else if ((scanner->getSensor().isPaperAtScan()))
|
||||||
|
{
|
||||||
|
LOG("------------------卡纸\r\n");
|
||||||
|
return FsmStateManagerEx<ErrorJamState>::GetState();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG("---------扫描仪已经准备完成------\r\n");
|
||||||
|
return FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitState::initial()
|
||||||
|
{
|
||||||
|
LOG("InitState 999 \n");
|
||||||
|
typeName = "InitState"; //啥用?
|
||||||
|
scanner->put(S_EVT_NORES);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorJamState::initial()
|
||||||
|
{
|
||||||
|
LOG("ErrorJamState \n");
|
||||||
|
typeName = "ErrorJamState";
|
||||||
|
scanner->getPanelLeds().setStatus(LedStatus::Abnormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorJamState::doPaper_pullout()
|
||||||
|
{
|
||||||
|
scanner->paper_pullout();
|
||||||
|
}
|
||||||
|
|
||||||
|
FsmState *ErrorJamState::on_event(ScanEvent event)
|
||||||
|
{
|
||||||
|
//LOG("ErrorJamState on_event %d \n", event);
|
||||||
|
if (scanner->getSensor().isCoverClosed() && !scanner->getSensor().isPaperStandby() && !scanner->getSensor().isPaperIn())
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_COVER_OPENED)
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<CoverOpenState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_PAPER_PULLOUT) // && scanner->GetIsDoublePaper()
|
||||||
|
{
|
||||||
|
scanner->paper_pullout();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_CLEAR_ERR)
|
||||||
|
{
|
||||||
|
if (!scanner->getSensor().isCoverClosed())
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<CoverOpenState>::GetState();
|
||||||
|
}
|
||||||
|
else //if (scanner->getSensor().isPaperStandby() && !scanner->getSensor().isPaperIn())
|
||||||
|
{
|
||||||
|
//LOG("ErrorJamState GetIsDoublePaper %s \n", scanner->GetIsDoublePaper() ? "TRUE" : "FALSE");
|
||||||
|
//LOG("ErrorJamState GetIsJamPaper %s \n", scanner->GetIsJamPaper() ? "TRUE" : "FALSE");
|
||||||
|
if (!scanner->GetIsDoublePaper() && !scanner->GetIsJamPaper() && !scanner->getSensor().isPaperAtScan())
|
||||||
|
{
|
||||||
|
if (scanner->getSensor().isPaperStandby())
|
||||||
|
return FsmStateManagerEx<PaperReadyState>::GetState();
|
||||||
|
else
|
||||||
|
return FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaperReadyState::initial()
|
||||||
|
{
|
||||||
|
|
||||||
|
LOG("PaperReadyState setStatus(PanelLeds::Ready) \n");
|
||||||
|
typeName = "PaperReadyState";
|
||||||
|
scanner->getPanelLeds().setStatus(LedStatus::Ready);
|
||||||
|
}
|
||||||
|
|
||||||
|
FsmState *PaperReadyState::on_event(ScanEvent event)
|
||||||
|
{
|
||||||
|
LOG("FsmState PaperReadyState on_event %d \n",event);
|
||||||
|
if (event == S_EVT_COVER_OPENED)
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<CoverOpenState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_PAPER_NOT_STANDBY)
|
||||||
|
{
|
||||||
|
if (!scanner->getSensor().isPaperStandby())
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_PAPER_AT_SCAN)
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<ErrorState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_START_SCAN)
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<ScanningState>::GetState();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorState::initial()
|
||||||
|
{
|
||||||
|
LOG("ErrorState \n");
|
||||||
|
typeName = "ErrorState";
|
||||||
|
scanner->getPanelLeds().setStatus(LedStatus::Abnormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
FsmState *ErrorState::on_event(ScanEvent event)
|
||||||
|
{
|
||||||
|
LOG("ErrorState on_event %d \n", event);
|
||||||
|
if (event == S_EVT_COVER_OPENED)
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<CoverOpenState>::GetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scanner->getSensor().isCoverClosed() && !scanner->getSensor().isPaperStandby() && scanner->getSensor().isPaperIn())
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_PAPER_STANDBY)
|
||||||
|
{
|
||||||
|
LOG("ErrorState on_event S_EVT_PAPER_STANDBY\n");
|
||||||
|
if (scanner->getSensor().isPaperStandby()) //有纸 且没卡纸
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<PaperReadyState>::GetState();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scanner->ResetJamIn();
|
||||||
|
return FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_CLEAR_ERR)
|
||||||
|
{
|
||||||
|
if (!scanner->getSensor().isCoverClosed()) //没关盖
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<CoverOpenState>::GetState();
|
||||||
|
}
|
||||||
|
else if (!scanner->GetIsJamIn())
|
||||||
|
{
|
||||||
|
if (scanner->getSensor().isPaperStandby()) //有纸 且没卡纸
|
||||||
|
{
|
||||||
|
if (!scanner->getSensor().isPaperIn())
|
||||||
|
return FsmStateManagerEx<PaperReadyState>::GetState();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScanningState::initial()
|
||||||
|
{
|
||||||
|
LOG("ScanningState \n");
|
||||||
|
typeName = "ScanningState";
|
||||||
|
scanner->getPanelLeds().setStatus(LedStatus::Scanning);
|
||||||
|
scanner->startScan();
|
||||||
|
}
|
||||||
|
|
||||||
|
FsmState *ScanningState::on_event(ScanEvent event)
|
||||||
|
{
|
||||||
|
LOG("ScanningState on_event \n");
|
||||||
|
if (event == S_EVT_COVER_IN_OPEN)
|
||||||
|
{
|
||||||
|
return FsmStateManagerEx<CoverOpenState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_STOP_SCAN)
|
||||||
|
{
|
||||||
|
LOG("ScanningState call for %d \n", event);
|
||||||
|
scanner->getPanelLeds().setStatus(LedStatus::StopScan);
|
||||||
|
scanner->stop_scan();
|
||||||
|
auto ret = scanner->getSensor().isPaperStandby() ? FsmStateManagerEx<PaperReadyState>::GetState() : FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
return ret;
|
||||||
|
// if (scanner->getSensor().isPaperStandby())
|
||||||
|
// {
|
||||||
|
// return FsmStateManagerEx<PaperReadyState>::GetState();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// return FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_COVER_OPENED)
|
||||||
|
{
|
||||||
|
//scanner->stop_scan();
|
||||||
|
scanner->emergency_stop(S_EVT_COVER_OPENED);
|
||||||
|
return FsmStateManagerEx<CoverOpenState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_DOUBLEPAPER)
|
||||||
|
{
|
||||||
|
scanner->SetIsDoublePaper(true);
|
||||||
|
scanner->emergency_stop(1);
|
||||||
|
LOG("\nScanningState S_EVT_DOUBLEPAPER %s \n",GetCurrentTimeStamp(2).c_str());
|
||||||
|
writesyslog(LOG_INFO,"double paper error\n");
|
||||||
|
return FsmStateManagerEx<ErrorJamState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_JAM_IN)
|
||||||
|
{
|
||||||
|
scanner->emergency_stop(0);
|
||||||
|
LOG("ScanningState S_EVT_JAM_IN \n");
|
||||||
|
return FsmStateManagerEx<ErrorState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_JAM_OUT)
|
||||||
|
{
|
||||||
|
scanner->emergency_stop(0);
|
||||||
|
LOG("ScanningState S_EVT_JAM_OUT \n");
|
||||||
|
return FsmStateManagerEx<ErrorJamState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_PAPER_AT_SCAN)
|
||||||
|
{
|
||||||
|
//ToDo:add notifyAll operation
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_PAPER_NOT_AT_SCAN)
|
||||||
|
{
|
||||||
|
//ToDo:add notifyAll operation
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_SAMPLE_ERR)
|
||||||
|
{
|
||||||
|
scanner->stop_scan();
|
||||||
|
return FsmStateManagerEx<ErrorState>::GetState();
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_PAPER_NOT_STANDBY)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(chrono::milliseconds(100));
|
||||||
|
if(!scanner->getSensor().isPaperStandby())
|
||||||
|
{
|
||||||
|
scanner->stop_scan();
|
||||||
|
return FsmStateManagerEx<StandbyState>::GetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <string>
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
#include "utilsfunc.h"
|
||||||
|
|
||||||
|
class Scanner;
|
||||||
|
|
||||||
|
|
||||||
|
enum ScanEvent {
|
||||||
|
S_EVT_NORES = 0x0,
|
||||||
|
S_EVT_SCAN_FINISHED = 0x2,
|
||||||
|
S_EVT_CLEAR_ERR = 0x03,
|
||||||
|
S_EVT_PAPER_PULLOUT = 0x05,
|
||||||
|
S_EVT_COVER_OPENED = 0x01,
|
||||||
|
S_EVT_COVER_CLOSED = 0x102,
|
||||||
|
S_EVT_PAPER_AT_SCAN = 0x08,
|
||||||
|
S_EVT_PAPER_NOT_AT_SCAN = 0x106,
|
||||||
|
S_EVT_DOUBLEPAPER = 0x110,
|
||||||
|
S_EVT_NOT_DOUBLEPAPER = 0x111,
|
||||||
|
S_EVT_START_SCAN = 0x45,
|
||||||
|
S_EVT_STOP_SCAN = 0x46,
|
||||||
|
S_EVT_SCAN_STARTED = 0x112,
|
||||||
|
S_EVT_SCAN_STOPPED = 0x113,
|
||||||
|
S_EVT_JAM_IN = 0x114,
|
||||||
|
S_EVT_JAM_OUT = 0x115,
|
||||||
|
S_EVT_SAMPLE_ERR = 0x116,
|
||||||
|
S_EVT_COVER_IN_OPEN = 0x117,
|
||||||
|
S_EVT_ERROR_PICKING = 0x4,
|
||||||
|
S_EVT_ERROR_JAM = 0x8,
|
||||||
|
S_EVT_ERROR_DOUBLEPAPER = 0x10,
|
||||||
|
S_EVT_ERROR_STAPLE = 0x20,
|
||||||
|
S_EVT_ERROR_FPGA = 0x44,
|
||||||
|
S_EVT_HAVING_IMAGE = 0x47,
|
||||||
|
S_EVT_ONE_PAPER_END = 0x59,
|
||||||
|
S_EVT_PAPER_NOT_STANDBY = 0,//?
|
||||||
|
S_EVT_PAPER_STANDBY = 0 //?
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FsmState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FsmState();
|
||||||
|
virtual ~FsmState();
|
||||||
|
|
||||||
|
virtual FsmState* on_event(ScanEvent event) = 0;
|
||||||
|
virtual void initial() {}
|
||||||
|
|
||||||
|
static void setScanner(Scanner* scan) {
|
||||||
|
scanner = scan;
|
||||||
|
}
|
||||||
|
std::string typeName = "FsmState";
|
||||||
|
protected:
|
||||||
|
static Scanner* scanner;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FsmStateManager
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
static std::map<std::string, std::shared_ptr<FsmState>> fsmStates;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class FsmStateManagerEx : public FsmStateManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static FsmState* GetState()
|
||||||
|
{
|
||||||
|
std::string type_name = typeid(T).name();
|
||||||
|
std::map<std::string, std::shared_ptr<FsmState>>::iterator iter = fsmStates.find(type_name);
|
||||||
|
if (iter == fsmStates.end()) {
|
||||||
|
fsmStates.insert(std::pair<std::string, std::shared_ptr<FsmState>>(type_name, std::shared_ptr<FsmState>(new T)));
|
||||||
|
}
|
||||||
|
fsmStates[type_name]->initial();
|
||||||
|
return fsmStates[type_name].get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//????
|
||||||
|
class StandbyState :public FsmState {
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void initial();
|
||||||
|
|
||||||
|
virtual FsmState* on_event(ScanEvent event);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void doReset();
|
||||||
|
};
|
||||||
|
|
||||||
|
//?????
|
||||||
|
class CoverOpenState : public FsmState {
|
||||||
|
public:
|
||||||
|
virtual void initial();
|
||||||
|
|
||||||
|
virtual FsmState* on_event(ScanEvent event);
|
||||||
|
};
|
||||||
|
|
||||||
|
class InitState :public FsmState {
|
||||||
|
public:
|
||||||
|
InitState();
|
||||||
|
|
||||||
|
virtual FsmState* on_event(ScanEvent event);
|
||||||
|
virtual void initial();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ErrorJamState : public FsmState {
|
||||||
|
|
||||||
|
public:
|
||||||
|
ErrorJamState() {}
|
||||||
|
|
||||||
|
virtual void initial();
|
||||||
|
|
||||||
|
virtual FsmState* on_event(ScanEvent event);
|
||||||
|
void doPaper_pullout();
|
||||||
|
};
|
||||||
|
|
||||||
|
class PaperReadyState : public FsmState {
|
||||||
|
|
||||||
|
public:
|
||||||
|
PaperReadyState() {}
|
||||||
|
virtual void initial();
|
||||||
|
|
||||||
|
FsmState* on_event(ScanEvent event);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ErrorState : public FsmState {
|
||||||
|
|
||||||
|
public:
|
||||||
|
ErrorState() {}
|
||||||
|
virtual void initial();
|
||||||
|
|
||||||
|
virtual FsmState* on_event(ScanEvent event);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScanningState : public FsmState {
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScanningState() {}
|
||||||
|
|
||||||
|
virtual void initial();
|
||||||
|
|
||||||
|
virtual FsmState* on_event(ScanEvent event);
|
||||||
|
};
|
|
@ -0,0 +1,74 @@
|
||||||
|
//
|
||||||
|
// Created by yingluo907 on 2019/4/11.
|
||||||
|
//
|
||||||
|
#include "Gpio.h"
|
||||||
|
#include "DevUtil.h"
|
||||||
|
|
||||||
|
#define IOPATH "%s/gpio%d/%s"
|
||||||
|
|
||||||
|
const std::string Gpio::falling = "falling";
|
||||||
|
const std::string Gpio::rising = "rising";
|
||||||
|
const std::string Gpio::both = "both";
|
||||||
|
const std::string Gpio::none = "none";
|
||||||
|
|
||||||
|
const std::string Gpio::in = "in";
|
||||||
|
const std::string Gpio::out = "out";
|
||||||
|
|
||||||
|
Gpio::Gpio(int port)
|
||||||
|
{
|
||||||
|
this->port = port;
|
||||||
|
path_value = string_format(IOPATH, path_gpiobase.c_str(), port, path_value.c_str());
|
||||||
|
path_edge = string_format(IOPATH, path_gpiobase.c_str(), port, path_edge.c_str());
|
||||||
|
path_direction = string_format(IOPATH, path_gpiobase.c_str(), port, path_direction.c_str());
|
||||||
|
path_active_low = string_format(IOPATH, path_gpiobase.c_str(), port, path_active_low.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int Gpio::getPort()
|
||||||
|
{
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::setValue(GpioLevel level)
|
||||||
|
{
|
||||||
|
write_dev(path_value, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
Gpio::GpioLevel Gpio::getValue() {
|
||||||
|
return (Gpio::GpioLevel)read_dev_i(path_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Gpio::getDirection()
|
||||||
|
{
|
||||||
|
return read_dev_s(path_direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::setDirection(std::string direction)
|
||||||
|
{
|
||||||
|
write_dev(path_direction, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::setActive(GpioLevel level)
|
||||||
|
{
|
||||||
|
write_dev(path_active_low, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
Gpio::GpioLevel Gpio::getActive()
|
||||||
|
{
|
||||||
|
return (GpioLevel)read_dev_i(path_active_low);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::setEdge(std::string edge)
|
||||||
|
{
|
||||||
|
write_dev(path_edge, edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Gpio::getEdge()
|
||||||
|
{
|
||||||
|
return read_dev_s(path_edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
GpioOut::GpioOut(int port) :
|
||||||
|
Gpio(port)
|
||||||
|
{
|
||||||
|
setDirection(out);
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
//
|
||||||
|
// Created by yingluo907 on 2019/4/11.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HGSCANSERVICE_GPIO_H
|
||||||
|
#define HGSCANSERVICE_GPIO_H
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Gpio {
|
||||||
|
public:
|
||||||
|
enum GpioLevel {
|
||||||
|
Low,
|
||||||
|
High
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
static const std::string falling;
|
||||||
|
static const std::string rising;
|
||||||
|
static const std::string both;
|
||||||
|
static const std::string none;
|
||||||
|
|
||||||
|
static const std::string in;
|
||||||
|
static const std::string out;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Gpio(int port);
|
||||||
|
int getPort();
|
||||||
|
void setValue(GpioLevel level);
|
||||||
|
GpioLevel getValue();
|
||||||
|
std::string getDirection();
|
||||||
|
void setDirection(std::string direction);
|
||||||
|
void setActive(GpioLevel level);
|
||||||
|
GpioLevel getActive();
|
||||||
|
void setEdge(std::string edge);
|
||||||
|
std::string getEdge();
|
||||||
|
|
||||||
|
std::string getValuePath() {
|
||||||
|
return path_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string path_gpiobase = "/sys/class/gpio";
|
||||||
|
int port;
|
||||||
|
std::string path_value = "value";
|
||||||
|
std::string path_edge = "edge";
|
||||||
|
std::string path_direction = "direction";
|
||||||
|
std::string path_active_low = "active_low";
|
||||||
|
};
|
||||||
|
|
||||||
|
class GpioOut : public Gpio
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GpioOut(int port);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HGSCANSERVICE_GPIO_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,165 @@
|
||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-01-11 09:41:39
|
||||||
|
* @LastEditTime: 2022-11-18 14:09:29
|
||||||
|
* @LastEditors: Zhaozhonmin 1656963645@qq.com
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: \zynq_MSS\capimage\HCamDevice.h
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <linux/videodev2.h>
|
||||||
|
// #include "../cameraConfig.h"
|
||||||
|
//#include "../CameraParams.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
union CamZ_Reg_4
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int unuse_0 : 2;
|
||||||
|
unsigned int color_mode : 1;
|
||||||
|
unsigned int unuse_1 : 2;
|
||||||
|
unsigned int encode_divide : 3;
|
||||||
|
unsigned int encode_divide_mode : 1;
|
||||||
|
unsigned int unuse_2 : 5;
|
||||||
|
unsigned int en_adc_cfg : 1;
|
||||||
|
unsigned int clr_exp : 1;
|
||||||
|
unsigned int soft_reset : 1;
|
||||||
|
unsigned int en_pattern : 1;
|
||||||
|
unsigned int line_enable : 1; //不使用
|
||||||
|
unsigned int byte_sync : 1;
|
||||||
|
unsigned int adc_config_all : 1 ;
|
||||||
|
unsigned int adc_select : 5 ;
|
||||||
|
unsigned int test_pattern : 1;
|
||||||
|
unsigned int gpio1 : 1 ;
|
||||||
|
unsigned int gpio2 : 1 ;
|
||||||
|
unsigned int reserved : 3;
|
||||||
|
}params;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define adcRegSize 20
|
||||||
|
#define REG_NUM 14
|
||||||
|
typedef std::function<void(uint32_t)> GetImgProcSize;
|
||||||
|
typedef std::function<void(uint32_t)> GetImgFormat;
|
||||||
|
typedef std::function<void(uint32_t)> GetCameraEvents;
|
||||||
|
typedef std::function<void(int)> ReLoadCorrecEvent;
|
||||||
|
//class Camconfig;
|
||||||
|
|
||||||
|
|
||||||
|
class HCamDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HCamDevice();
|
||||||
|
|
||||||
|
~HCamDevice();
|
||||||
|
|
||||||
|
int open_video();
|
||||||
|
int close_video();
|
||||||
|
|
||||||
|
void HtCamStartVideoCapturing();
|
||||||
|
void HtCamStopVideoCapturing();
|
||||||
|
int HtCamWaitVideoCapture(int msTimeout);
|
||||||
|
int HtCamReadCaptureFrame(void **pbuf, int timeout);
|
||||||
|
int width() { return v4lWidth; }
|
||||||
|
int height() { return v4lHeight; }
|
||||||
|
|
||||||
|
uint32_t HtCamReadFpgaRegs(uint8_t reg_addr);
|
||||||
|
void HtCamWriteFpgaRegs(uint8_t reg_addr, uint32_t reg_value);
|
||||||
|
void HtCamChangeTriggerInAndEXt(int in_out);
|
||||||
|
|
||||||
|
void HtCamSetTriggerMode(int val);
|
||||||
|
int HtCamGetTriggerMode();
|
||||||
|
int HtCamGetColorMode();
|
||||||
|
|
||||||
|
uint32_t HtCamReadPsRegs(uint8_t reg_addr);
|
||||||
|
void HtCamWritePsRegs(uint8_t reg_addr, uint32_t reg_value);
|
||||||
|
void savePsReg();
|
||||||
|
|
||||||
|
void HtCamWriteAllADC();
|
||||||
|
void HtCamInitADCReg();
|
||||||
|
void HtCamWriteADCReg(uint8_t addr,uint8_t data);
|
||||||
|
void HtCamReadADCReg(uint8_t addr, uint8_t *data);
|
||||||
|
|
||||||
|
void set_get_imgSize_event(GetImgProcSize _getImgProcSize);
|
||||||
|
void set_get_imgFormat_event(GetImgFormat _getImgFormat);
|
||||||
|
void set_reload_correct_event(ReLoadCorrecEvent _reLoadCorrectEvent);
|
||||||
|
|
||||||
|
void set_get_CameraEvents_event(GetCameraEvents _getCameraEvents);
|
||||||
|
void HtCamOverClockClear(); // 清除切换超频标志位
|
||||||
|
|
||||||
|
uint8_t getADCReg(int addr);
|
||||||
|
void setADCReg(int addr , uint8_t value);
|
||||||
|
void saveADCReg();
|
||||||
|
|
||||||
|
// void setConfig(Camconfig* _config){config = _config;}
|
||||||
|
void HtCamChangeMonoStartSample(int start_sample);
|
||||||
|
private:
|
||||||
|
int init_fd();
|
||||||
|
int init_sample();
|
||||||
|
int init_capture();
|
||||||
|
int init_video_buffer();
|
||||||
|
int init_dev();
|
||||||
|
void init_ps_regs();
|
||||||
|
void HtCamSwitchSampleModes(unsigned char mode);
|
||||||
|
void HtCamChangeExposureValue(unsigned int value);
|
||||||
|
void HtCamExitVideoCapturing();
|
||||||
|
void HtCamResizeBuffer(int width, int height, int number);
|
||||||
|
void HtCamChangeAdjustSpTime(uint32_t sp_time_gap, uint32_t sp_time_rw);
|
||||||
|
void HtCamChangeAdjustPhase(uint16_t times, uint8_t dir);
|
||||||
|
int HtCamStartSampling();
|
||||||
|
int HtCamStopSampling();
|
||||||
|
void HtCamChangeDpi(int dpi);
|
||||||
|
bool HtCamPsDpiChange(int dpi);
|
||||||
|
|
||||||
|
void HtCamImageProcessChange();
|
||||||
|
|
||||||
|
int HtCamEventWorkThread(void);
|
||||||
|
|
||||||
|
struct captureBuffer
|
||||||
|
{
|
||||||
|
void *start;
|
||||||
|
int dmabuf_fd;
|
||||||
|
uint32_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned int phyBaseAddr = 0x40010000;
|
||||||
|
const unsigned int AddrMapSize = 0x100;
|
||||||
|
unsigned int *virBaseAddr;
|
||||||
|
|
||||||
|
int memfd;
|
||||||
|
std::string subDeviceName;
|
||||||
|
int subDevicefd;
|
||||||
|
|
||||||
|
std::string videoDevName = "/dev/video0";
|
||||||
|
int videofd;
|
||||||
|
unsigned int v4lWidth;
|
||||||
|
unsigned int v4lHeight;
|
||||||
|
unsigned int v4lBufferCount;
|
||||||
|
int nplanes;
|
||||||
|
int drivertype;
|
||||||
|
enum v4l2_buf_type v4l2buftype;
|
||||||
|
enum v4l2_memory v4l2memtype;
|
||||||
|
struct captureBuffer *captureBufers;
|
||||||
|
int lastSucceedBufferIndex;
|
||||||
|
|
||||||
|
uint32_t pPsReg[ REG_NUM + 1] = {0};
|
||||||
|
uint8_t pADCReg[adcRegSize];
|
||||||
|
|
||||||
|
GetImgProcSize getImgProcSize;
|
||||||
|
GetImgFormat getImgFormat;
|
||||||
|
GetCameraEvents getCameraEvents = nullptr;
|
||||||
|
ReLoadCorrecEvent reLoadCorrectEvent = nullptr;
|
||||||
|
|
||||||
|
std::shared_ptr<std::thread> event_thread = nullptr;
|
||||||
|
//Camconfig* config = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include "HGUsb.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
HGUsb::HGUsb()
|
||||||
|
{
|
||||||
|
m_usbBulkIn.reset(new UsbEndPoint(UsbEndPoint::EndpointType::EP_Bulk_In));
|
||||||
|
m_usbBulkOut.reset(new UsbEndPoint(UsbEndPoint::EndpointType::EP_Bulk_Out));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HGUsb::~HGUsb()
|
||||||
|
{
|
||||||
|
if (m_usbBulkIn.get())
|
||||||
|
m_usbBulkIn.reset();
|
||||||
|
if (m_usbBulkOut.get())
|
||||||
|
m_usbBulkOut.reset();
|
||||||
|
if (m_usbCtl.get())
|
||||||
|
m_usbInt.reset();
|
||||||
|
if (m_usbInt.get())
|
||||||
|
m_usbInt.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
int HGUsb::open()
|
||||||
|
{
|
||||||
|
int ret = (int)HGUSB_ErrorCode::HG_USBSuccess;
|
||||||
|
if (is_connect())
|
||||||
|
{
|
||||||
|
LOG("PC has connected USB\n");
|
||||||
|
ret = m_usbBulkIn->open();
|
||||||
|
ret = m_usbBulkOut->open();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = (int)HGUSB_ErrorCode::HG_USBPCUnConnected;
|
||||||
|
LOG("PC havn't connected USB\n");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HGUsb::close()
|
||||||
|
{
|
||||||
|
m_usbBulkIn->close();
|
||||||
|
m_usbBulkOut->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
int HGUsb::read_bulk(void *pdata, int length)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (!pdata)
|
||||||
|
return (int)HGUSB_ErrorCode::HG_USBInvalidePtr;
|
||||||
|
if (m_usbBulkOut.get())
|
||||||
|
{
|
||||||
|
ret = m_usbBulkOut->read(pdata, length);
|
||||||
|
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HGUsb::write_bulk(void *pdata, int length)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (!pdata)
|
||||||
|
return (int)HGUSB_ErrorCode::HG_USBInvalidePtr;
|
||||||
|
if (m_usbBulkIn.get())
|
||||||
|
{
|
||||||
|
ret = m_usbBulkIn->write(pdata, length);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int HGUsb::write_int(void *pdata, int length)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (!pdata)
|
||||||
|
return (int)HGUSB_ErrorCode::HG_USBInvalidePtr;
|
||||||
|
if (m_usbInt.get())
|
||||||
|
m_usbInt->write(pdata, length);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HGUsb::write_control(int rtype, int req, int value, int index, int len, void *data)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (!data)
|
||||||
|
return (int)HGUSB_ErrorCode::HG_USBInvalidePtr;
|
||||||
|
if (m_usbCtl.get())
|
||||||
|
{
|
||||||
|
//need to transfer protocol,did not realized
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HGUsb::is_connect()
|
||||||
|
{
|
||||||
|
//DEBUG("check if PC and Scanner connected ");
|
||||||
|
int fd, n;
|
||||||
|
char buf[20] = "\0";
|
||||||
|
fd = ::open(STATE_PATH, O_RDONLY);
|
||||||
|
read(fd, buf, 20);
|
||||||
|
::close(fd);
|
||||||
|
return strstr(buf, "CONFIGURED");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool HGUsb::is_open()
|
||||||
|
{
|
||||||
|
return m_usbBulkIn->is_open() && m_usbBulkOut->is_open();
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include <memory>
|
||||||
|
#include "UsbEndpoint.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class HGUsb
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HGUsb();
|
||||||
|
~HGUsb();
|
||||||
|
int open();
|
||||||
|
void close();
|
||||||
|
int read_bulk(void *pdata, int length);
|
||||||
|
int write_bulk(void *pdata, int length);
|
||||||
|
int write_int(void *pdata, int length);
|
||||||
|
int write_control(int rtype, int req, int value, int index, int len, void *data);
|
||||||
|
bool is_connect();
|
||||||
|
bool is_open();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<UsbEndPoint> m_usbBulkIn;
|
||||||
|
std::unique_ptr<UsbEndPoint> m_usbBulkOut;
|
||||||
|
std::unique_ptr<UsbEndPoint> m_usbInt;
|
||||||
|
std::unique_ptr<UsbEndPoint> m_usbCtl;
|
||||||
|
};
|
|
@ -0,0 +1,62 @@
|
||||||
|
#pragma once
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
#include "BlockingQueue.h"
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
#include "gvideo.h"
|
||||||
|
|
||||||
|
#include "HCamDevice.h"
|
||||||
|
|
||||||
|
class FpgaComm;
|
||||||
|
|
||||||
|
class ICapturer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ICapturer() {}
|
||||||
|
|
||||||
|
virtual ~ICapturer() {}
|
||||||
|
|
||||||
|
virtual void SetParent(void *scanner) = 0;
|
||||||
|
|
||||||
|
virtual void open() = 0;
|
||||||
|
|
||||||
|
virtual void snap() = 0;
|
||||||
|
|
||||||
|
virtual void stopsnap(bool autosize) = 0;
|
||||||
|
|
||||||
|
virtual void close() = 0;
|
||||||
|
|
||||||
|
virtual int read(int addr) = 0;
|
||||||
|
|
||||||
|
virtual void *readFrameTest(int timeout) = 0;
|
||||||
|
|
||||||
|
virtual void UpdateScanParam(HG_ScanConfiguration config) = 0;
|
||||||
|
|
||||||
|
virtual void createCorrect(int correctmode) = 0;
|
||||||
|
|
||||||
|
virtual void setFPGATriggerMode(bool autotrigger, int delay) = 0;
|
||||||
|
|
||||||
|
virtual void setFanMode(int mode) = 0;
|
||||||
|
|
||||||
|
virtual void fpgaReload() = 0;
|
||||||
|
|
||||||
|
virtual bool capturerImage() = 0;
|
||||||
|
|
||||||
|
virtual void waitsnapdone(int state) = 0;
|
||||||
|
|
||||||
|
virtual bool IsImageQueueEmpty() = 0;
|
||||||
|
|
||||||
|
virtual void resetimageremain() = 0;
|
||||||
|
|
||||||
|
virtual std::atomic_int &getimageremain() = 0;
|
||||||
|
|
||||||
|
virtual void clearimages() = 0;
|
||||||
|
|
||||||
|
virtual void setScanFlag(bool brun) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<FpgaComm> m_capFpageregs;
|
||||||
|
BlockingQueue<V4L2_DATAINFO> m_v4l2data;
|
||||||
|
std::shared_ptr<HCamDevice> video;//Capturer 类内部自己初始化
|
||||||
|
HG_ScanConfiguration m_config;
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
#include "IPreproc.h"
|
||||||
|
|
||||||
|
IPreproc::IPreproc(void){}
|
||||||
|
|
||||||
|
IPreproc::~IPreproc(void){}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
//#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
class IPreproc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IPreproc(void);
|
||||||
|
|
||||||
|
virtual ~IPreproc(void);
|
||||||
|
|
||||||
|
//virtual int preprocess(cv::Mat& mat,void* unused=nullptr) = 0;
|
||||||
|
};
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
#include <string>
|
||||||
|
#include "BlockingQueue.h"
|
||||||
|
|
||||||
|
class IScanner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IScanner(/* args */) {}
|
||||||
|
virtual ~IScanner() {}
|
||||||
|
virtual void StartScan(int scancount) = 0;
|
||||||
|
virtual void StopScan() = 0;
|
||||||
|
virtual void ConfigScanParam(HG_ScanConfiguration config) = 0;
|
||||||
|
virtual bool FeederLoaded() = 0;
|
||||||
|
virtual std::string GetSerial() = 0;
|
||||||
|
virtual void SetSerial(std::string serial) = 0;
|
||||||
|
virtual std::string GetFWVersion() = 0;
|
||||||
|
virtual void SetFwVersion(std::string fwversion) = 0;
|
||||||
|
virtual int GetRollerNum() = 0;
|
||||||
|
virtual void ClearRollerNum() = 0;
|
||||||
|
virtual void InitScanner() = 0;
|
||||||
|
virtual void ClearImages() = 0;
|
||||||
|
virtual HG_JpegCompressInfo GetImage() = 0;
|
||||||
|
virtual HG_Msg GetEvent() = 0;
|
||||||
|
virtual void ClearErrorEvents() = 0;
|
||||||
|
virtual void ClearHWError() = 0;
|
||||||
|
virtual bool GetImagequeueEmpty() = 0;
|
||||||
|
virtual bool GetEventQueueEmpty() = 0;
|
||||||
|
virtual HG_JpegCompressInfo GetFrontImage() = 0;
|
||||||
|
virtual HG_Msg GetEventFront() = 0;
|
||||||
|
virtual void CreatCorrectData(int correctmode) = 0;
|
||||||
|
virtual bool IsScanning() = 0;
|
||||||
|
virtual void SetFlatParam(int type, int *value) = 0;
|
||||||
|
virtual CaptureParams GetCaptureParams() = 0;
|
||||||
|
virtual void UpdateScanInfo(int type, void *data) = 0;
|
||||||
|
virtual ScannerScanInfo GetScanInfo() = 0;
|
||||||
|
virtual void SetLEDStatus(LedStatus status) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BlockingQueue<HG_JpegCompressInfo> m_images;
|
||||||
|
BlockingQueue<HG_Msg> m_scannerEvents;
|
||||||
|
std::string m_serial;
|
||||||
|
std::string m_fwversion;
|
||||||
|
};
|
|
@ -0,0 +1,350 @@
|
||||||
|
// #include "ImageProcess_Public.h"
|
||||||
|
// #include "opencv2/imgproc/types_c.h"
|
||||||
|
// #include "opencv2/imgproc/imgproc_c.h"
|
||||||
|
// namespace hg
|
||||||
|
// {
|
||||||
|
// void convexHull(const std::vector<cv::Point>& src, std::vector<cv::Point>& dst, bool clockwise)
|
||||||
|
// {
|
||||||
|
// CvMemStorage* storage = cvCreateMemStorage(); //
|
||||||
|
// CvSeq* ptseq = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2, sizeof(CvContour), sizeof(CvPoint), storage); //ptseqstorage
|
||||||
|
|
||||||
|
// //将src的点集填充至ptseq
|
||||||
|
// for (const cv::Point& item : src)
|
||||||
|
// {
|
||||||
|
// CvPoint p;
|
||||||
|
// p.x = item.x;
|
||||||
|
// p.y = item.y;
|
||||||
|
// cvSeqPush(ptseq, &p);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //获取轮廓点
|
||||||
|
// CvSeq* hull = cvConvexHull2(ptseq, nullptr, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, 0);
|
||||||
|
|
||||||
|
// if (hull == nullptr)
|
||||||
|
// {
|
||||||
|
// //释放storage
|
||||||
|
// cvReleaseMemStorage(&storage);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //填充dst
|
||||||
|
// dst.clear();
|
||||||
|
// for (int i = 0, hullCount = hull->total; i < hullCount; i++)
|
||||||
|
// dst.push_back(**CV_GET_SEQ_ELEM(CvPoint*, hull, i));
|
||||||
|
|
||||||
|
// //释放storage
|
||||||
|
// cvReleaseMemStorage(&storage);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #define R_COLOR 255
|
||||||
|
// void fillConvexHull(cv::Mat& image, const std::vector<cv::Point>& points)
|
||||||
|
// {
|
||||||
|
// uint index_top = 0;
|
||||||
|
// uint index_bottom = 0;
|
||||||
|
// for (size_t i = 0, length = points.size(); i < length; i++)
|
||||||
|
// {
|
||||||
|
// if (points[i].y < points[index_top].y)
|
||||||
|
// index_top = i;
|
||||||
|
// if (points[i].y > points[index_bottom].y)
|
||||||
|
// index_bottom = i;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::vector<cv::Point> edge_left;
|
||||||
|
// uint temp = index_top;
|
||||||
|
// while (temp != index_bottom)
|
||||||
|
// {
|
||||||
|
// edge_left.push_back(points[temp]);
|
||||||
|
// temp = (temp + points.size() - 1) % points.size();
|
||||||
|
// }
|
||||||
|
// edge_left.push_back(points[index_bottom]);
|
||||||
|
|
||||||
|
// std::vector<cv::Point> edge_right;
|
||||||
|
// temp = index_top;
|
||||||
|
// while (temp != index_bottom)
|
||||||
|
// {
|
||||||
|
// edge_right.push_back(points[temp]);
|
||||||
|
// temp = (temp + points.size() + 1) % points.size();
|
||||||
|
// }
|
||||||
|
// edge_right.push_back(points[index_bottom]);
|
||||||
|
|
||||||
|
// std::vector<int> left_edge_x;
|
||||||
|
// std::vector<int> left_edge_y;
|
||||||
|
// for (size_t i = 0, length = edge_left.size() - 1; i < length; i++)
|
||||||
|
// {
|
||||||
|
// int y_top = edge_left[i].y;
|
||||||
|
// int x_top = edge_left[i].x;
|
||||||
|
// int y_bottom = edge_left[i + 1].y;
|
||||||
|
// int x_bottom = edge_left[i + 1].x;
|
||||||
|
// for (int y = y_top; y < y_bottom; y++)
|
||||||
|
// if (y >= 0 && y_top != y_bottom && y < image.rows)
|
||||||
|
// {
|
||||||
|
// left_edge_x.push_back(((x_bottom - x_top) * y + x_top * y_bottom - x_bottom * y_top) / (y_bottom - y_top));
|
||||||
|
// left_edge_y.push_back(y);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// size_t step = image.step;
|
||||||
|
// unsigned char* ptr;
|
||||||
|
// ptr = image.data + static_cast<uint>(left_edge_y[0]) * step;
|
||||||
|
// for (size_t i = 0, length = left_edge_x.size(); i < length; i++)
|
||||||
|
// {
|
||||||
|
// int pix = left_edge_x[i];
|
||||||
|
// if (pix < image.cols - 1 && pix > 0)
|
||||||
|
// memset(ptr + i * step, R_COLOR, static_cast<size_t>((pix + 1) * image.channels()));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::vector<int> right_edge_x;
|
||||||
|
// std::vector<int> right_edge_y;
|
||||||
|
// for (size_t i = 0, length = edge_right.size() - 1; i < length; i++)
|
||||||
|
// {
|
||||||
|
// int y_top = edge_right[i].y;
|
||||||
|
// int x_top = edge_right[i].x;
|
||||||
|
// int y_bottom = edge_right[i + 1].y;
|
||||||
|
// int x_bottom = edge_right[i + 1].x;
|
||||||
|
// for (int y = y_top; y < y_bottom; y++)
|
||||||
|
// if (y_top != y_bottom && y < image.rows && y >= 0)
|
||||||
|
// {
|
||||||
|
// right_edge_x.push_back(((x_bottom - x_top) * y + x_top * y_bottom - x_bottom * y_top) / (y_bottom - y_top));
|
||||||
|
// right_edge_y.push_back(y);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ptr = image.data + static_cast<uint>(right_edge_y[0]) * step;
|
||||||
|
// for (size_t i = 0, length = right_edge_x.size(); i < length; i++)
|
||||||
|
// {
|
||||||
|
// int pix = right_edge_x[i];
|
||||||
|
// if (pix < image.cols - 1 && pix > 0)
|
||||||
|
// memset(ptr + i * step + pix * image.channels(), R_COLOR, step - static_cast<size_t>(pix * image.channels()));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (edge_left[0].y > 0)
|
||||||
|
// memset(image.data, R_COLOR, static_cast<size_t>(edge_left[0].y) * step);
|
||||||
|
|
||||||
|
// if (edge_left.back().y < image.rows - 1)
|
||||||
|
// memset(image.data + static_cast<size_t>(edge_left.back().y) * step, R_COLOR,
|
||||||
|
// static_cast<size_t>(image.rows - edge_left.back().y) * step);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void fillPolys(cv::Mat& image, const std::vector<std::vector<cv::Point>>& contours, const cv::Scalar& color)
|
||||||
|
// {
|
||||||
|
// if (contours.empty()) return;
|
||||||
|
|
||||||
|
// size_t count = contours.size();
|
||||||
|
// cv::Point** pointss = new cv::Point*[count];
|
||||||
|
// int* npts = new int[count];
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < count; i++)
|
||||||
|
// {
|
||||||
|
// size_t length = contours[i].size();
|
||||||
|
// npts[i] = length;
|
||||||
|
// pointss[i] = new cv::Point[length];
|
||||||
|
// for (size_t j = 0; j < length; j++)
|
||||||
|
// pointss[i][j] = contours[i][j];
|
||||||
|
// }
|
||||||
|
// cv::fillPoly(image, const_cast<const cv::Point**>(pointss), npts, count, color);
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < count; i++)
|
||||||
|
// delete[] pointss[i];
|
||||||
|
|
||||||
|
// delete[] pointss;
|
||||||
|
// delete[] npts;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset)
|
||||||
|
// {
|
||||||
|
// #if CV_VERSION_REVISION == 6
|
||||||
|
// CvMat c_image = src;
|
||||||
|
// #else
|
||||||
|
// CvMat c_image;
|
||||||
|
// c_image = cvMat(src.rows, src.cols, src.type(), src.data);
|
||||||
|
// c_image.step = src.step[0];
|
||||||
|
// c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (src.flags & cv::Mat::CONTINUOUS_FLAG);
|
||||||
|
// #endif
|
||||||
|
// cv::MemStorage storage(cvCreateMemStorage());
|
||||||
|
// CvSeq* _ccontours = nullptr;
|
||||||
|
|
||||||
|
// #if CV_VERSION_REVISION == 6
|
||||||
|
// cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset));
|
||||||
|
// #else
|
||||||
|
// cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint{ offset.x, offset.y });
|
||||||
|
// #endif
|
||||||
|
// if (!_ccontours)
|
||||||
|
// {
|
||||||
|
// contours.clear();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// cv::Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
|
||||||
|
// size_t total = all_contours.size();
|
||||||
|
// contours.resize(total);
|
||||||
|
|
||||||
|
// cv::SeqIterator<CvSeq*> it = all_contours.begin();
|
||||||
|
// for (size_t i = 0; i < total; i++, ++it)
|
||||||
|
// {
|
||||||
|
// CvSeq* c = *it;
|
||||||
|
// reinterpret_cast<CvContour*>(c)->color = static_cast<int>(i);
|
||||||
|
// int count = c->total;
|
||||||
|
// int* data = new int[static_cast<size_t>(count * 2)];
|
||||||
|
// cvCvtSeqToArray(c, data);
|
||||||
|
// for (int j = 0; j < count; j++)
|
||||||
|
// {
|
||||||
|
// contours[i].push_back(cv::Point(data[j * 2], data[j * 2 + 1]));
|
||||||
|
// }
|
||||||
|
// delete[] data;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// hierarchy.resize(total);
|
||||||
|
// it = all_contours.begin();
|
||||||
|
// for (size_t i = 0; i < total; i++, ++it)
|
||||||
|
// {
|
||||||
|
// CvSeq* c = *it;
|
||||||
|
// int h_next = c->h_next ? reinterpret_cast<CvContour*>(c->h_next)->color : -1;
|
||||||
|
// int h_prev = c->h_prev ? reinterpret_cast<CvContour*>(c->h_prev)->color : -1;
|
||||||
|
// int v_next = c->v_next ? reinterpret_cast<CvContour*>(c->v_next)->color : -1;
|
||||||
|
// int v_prev = c->v_prev ? reinterpret_cast<CvContour*>(c->v_prev)->color : -1;
|
||||||
|
// hierarchy[i] = cv::Vec4i(h_next, h_prev, v_next, v_prev);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// storage.release();
|
||||||
|
// }
|
||||||
|
// cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour)
|
||||||
|
// {
|
||||||
|
// if (contour.empty()) return {};
|
||||||
|
|
||||||
|
// cv::RotatedRect rect = minAreaRect(contour);
|
||||||
|
// printf("!!!!!!!!!!!!!!!!!!rect width = %f height = %f \n",rect.size.width,rect.size.height);
|
||||||
|
// if (rect.angle < -45)
|
||||||
|
// {
|
||||||
|
// rect.angle += 90;
|
||||||
|
// float temp = rect.size.width;
|
||||||
|
// rect.size.width = rect.size.height;
|
||||||
|
// rect.size.height = temp;
|
||||||
|
// }
|
||||||
|
// if (rect.angle > 45)
|
||||||
|
// {
|
||||||
|
// rect.angle -= 90;
|
||||||
|
// float temp = rect.size.width;
|
||||||
|
// rect.size.width = rect.size.height;
|
||||||
|
// rect.size.height = temp;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return rect;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::vector<cv::Point> getMaxContour(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy)
|
||||||
|
// {
|
||||||
|
// std::vector<cv::Point> maxContour;
|
||||||
|
// if (contours.size() < 1) return {};
|
||||||
|
|
||||||
|
// for (size_t i = 0, length = hierarchy.size(); i < length; i++)
|
||||||
|
// if (hierarchy[i][3] == -1)
|
||||||
|
// for (const auto &item : contours[i])
|
||||||
|
// maxContour.push_back(item);
|
||||||
|
|
||||||
|
// return maxContour;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::vector<cv::Point> getVertices(const cv::RotatedRect& rect)
|
||||||
|
// {
|
||||||
|
// cv::Point2f box[4];
|
||||||
|
// rect.points(box);
|
||||||
|
// std::vector<cv::Point> points;
|
||||||
|
// for (int i = 0; i < 4; i++)
|
||||||
|
// points.push_back(cv::Point(box[i]));
|
||||||
|
|
||||||
|
// return points;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void polyIndent(std::vector<cv::Point>& points, const cv::Point& center, int indent)
|
||||||
|
// {
|
||||||
|
// static cv::Point zero(0, 0);
|
||||||
|
// for (cv::Point& item : points)
|
||||||
|
// {
|
||||||
|
// #if 0
|
||||||
|
// cv::Point vec = item - center;
|
||||||
|
// if (vec != zero)
|
||||||
|
// {
|
||||||
|
// int length = vec.x * vec.x + vec.y * vec.y;
|
||||||
|
// float x = cv::sqrt(static_cast<float>(vec.x * vec.x / length)) * indent;
|
||||||
|
// float y = cv::sqrt(static_cast<float>(vec.y * vec.y / length)) * indent;
|
||||||
|
|
||||||
|
// if (vec.x < 0) x *= -1.0f;
|
||||||
|
// if (vec.y < 0) y *= -1.0f;
|
||||||
|
|
||||||
|
// item.x -= static_cast<int>(x);
|
||||||
|
// item.y -= static_cast<int>(y);
|
||||||
|
// }
|
||||||
|
// #else
|
||||||
|
// if (item.x > center.x)
|
||||||
|
// item.x -= indent;
|
||||||
|
// else
|
||||||
|
// item.x += indent;
|
||||||
|
|
||||||
|
// if (item.y > center.y)
|
||||||
|
// item.y -= indent;
|
||||||
|
// else
|
||||||
|
// item.y += indent;
|
||||||
|
// #endif
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat transforColor(const cv::Mat& src)
|
||||||
|
// {
|
||||||
|
// if (src.channels() == 1) return src.clone();
|
||||||
|
|
||||||
|
// std::vector<cv::Mat> channels(3);
|
||||||
|
// cv::split(src, channels);
|
||||||
|
|
||||||
|
// cv::Mat temp, dst;
|
||||||
|
// bitwise_or(channels[0], channels[1], temp);
|
||||||
|
// bitwise_or(channels[2], temp, dst);
|
||||||
|
// temp.release();
|
||||||
|
|
||||||
|
// for (cv::Mat& index : channels)
|
||||||
|
// index.release();
|
||||||
|
// return dst;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre)
|
||||||
|
// {
|
||||||
|
// if (src.channels() == 3)
|
||||||
|
// {
|
||||||
|
// #ifdef USE_ONENCL
|
||||||
|
// if (cl_res.context)
|
||||||
|
// transforColor_threshold_opencl(src, dst, static_cast<uchar>(thre));
|
||||||
|
// else
|
||||||
|
// #endif
|
||||||
|
// {
|
||||||
|
// cv::Mat gray = transforColor(src);
|
||||||
|
// cv::threshold(gray, dst, thre, 255, cv::THRESH_BINARY);
|
||||||
|
// gray.release();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// cv::threshold(src, dst, thre, 255, cv::THRESH_BINARY);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Point warpPoint(const cv::Point& p, const cv::Mat& warp_mat)
|
||||||
|
// {
|
||||||
|
// double src_data[3] = { static_cast<double>(p.x), static_cast<double>(p.y), 1 };
|
||||||
|
// cv::Mat src(3, 1, warp_mat.type(), src_data); //warp_mat.type() == CV_64FC1
|
||||||
|
|
||||||
|
// cv::Mat dst = warp_mat * src;
|
||||||
|
// double* ptr = reinterpret_cast<double*>(dst.data);
|
||||||
|
// return cv::Point(static_cast<int>(ptr[0]), static_cast<int>(ptr[1]));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// int distanceP2P(const cv::Point& p1, const cv::Point& p2)
|
||||||
|
// {
|
||||||
|
// return cv::sqrt(cv::pow(p1.x - p2.x, 2) + cv::pow(p1.y - p2.y, 2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// float distanceP2L(const cv::Point& p, const cv::Point& l1, const cv::Point& l2)
|
||||||
|
// {
|
||||||
|
// //求直线方程
|
||||||
|
// int A = 0, B = 0, C = 0;
|
||||||
|
// A = l1.y - l2.y;
|
||||||
|
// B = l2.x - l1.x;
|
||||||
|
// C = l1.x * l2.y - l1.y * l2.x;
|
||||||
|
// //代入点到直线距离公式
|
||||||
|
// return ((float)abs(A * p.x + B * p.y + C)) / ((float)sqrtf(A * A + B * B));
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -0,0 +1,130 @@
|
||||||
|
// /*
|
||||||
|
// * ====================================================
|
||||||
|
|
||||||
|
// * 功能:公共图像处理算法。部分功能可能会在ImageProcess里面多个类反复使用
|
||||||
|
// * 作者:刘丁维
|
||||||
|
// * 生成时间:2020/4/21
|
||||||
|
// * 最近修改时间:2020/4/21
|
||||||
|
// * 2021/07/12 v1.1 getBoundingRect中,增加考虑纠正初始 angle > 90 的情况。
|
||||||
|
// * 2021/07/22 v1.2 convexHull中,修复点集为空可能导致崩溃的BUG。
|
||||||
|
// * 版本号:v1.2
|
||||||
|
|
||||||
|
// * ====================================================
|
||||||
|
// */
|
||||||
|
|
||||||
|
// #ifndef IMAGE_PROCESS_PUBLIC_H
|
||||||
|
// #define IMAGE_PROCESS_PUBLIC_H
|
||||||
|
|
||||||
|
// #include "opencv2/opencv.hpp"
|
||||||
|
// #include <vector>
|
||||||
|
|
||||||
|
// namespace hg
|
||||||
|
// {
|
||||||
|
// /*
|
||||||
|
// * 功能:计算源点集的凸多边形轮廓,输出轮廓点集
|
||||||
|
// * src: 源点集
|
||||||
|
// * dst: 目标点集
|
||||||
|
// * clockwise: true为顺时针排序,false为逆时针排序
|
||||||
|
// */
|
||||||
|
// void convexHull(const std::vector<cv::Point>& src, std::vector<cv::Point>& dst, bool clockwise = false);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能:填充凸多边形,默认颜色为白色
|
||||||
|
// * image: 填充图像
|
||||||
|
// * points: 凸多边形轮廓点集(逆时针排序)
|
||||||
|
// */
|
||||||
|
// void fillConvexHull(cv::Mat& image, const std::vector<cv::Point>& points);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能:填充凹多边形
|
||||||
|
// * image: 填充图像
|
||||||
|
// * contours: 凹多边形轮廓点集(逆时针排序)
|
||||||
|
// * color: 填充颜色
|
||||||
|
// */
|
||||||
|
// void fillPolys(cv::Mat& image, const std::vector<std::vector<cv::Point>>& contours, const cv::Scalar& color);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能:获取连通区域轮廓
|
||||||
|
// * src: 源图像
|
||||||
|
// * contours: 结果轮廓集
|
||||||
|
// * hierarchy: 轮廓集的排序关系。与contours的数量对应,受retr选项不同,排序会有变化
|
||||||
|
// * retr: 轮廓集排序方式,默认为链式排序
|
||||||
|
// * method: 查找算法选择,默认为普通查找
|
||||||
|
// * offset: 查找起始点,默认为(0,0)点
|
||||||
|
// */
|
||||||
|
// void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy,
|
||||||
|
// int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0));
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能:获取覆盖点集的最小外接矩形
|
||||||
|
// * contour: 点集
|
||||||
|
// * 返回值: 旋转矩形
|
||||||
|
// */
|
||||||
|
// cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能: 获取覆盖轮廓集的最小外接凸多边形轮廓
|
||||||
|
// * contours: 轮廓集(每个轮廓由点集组成)
|
||||||
|
// * hierarchy: 轮廓集中,轮廓之间的关系。数量与contours对应
|
||||||
|
// * 返回值: 凸多边形轮廓点集
|
||||||
|
// */
|
||||||
|
// std::vector<cv::Point> getMaxContour(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能: 获取覆盖轮廓集的最小外接凸多边形轮廓
|
||||||
|
// * contours: 轮廓集(每个轮廓由点集组成)
|
||||||
|
// * hierarchy: 轮廓集中,轮廓之间的关系。数量与contours对应
|
||||||
|
// * 返回值: 凸多边形轮廓点集
|
||||||
|
// */
|
||||||
|
// std::vector<cv::Point> getVertices(const cv::RotatedRect& rect);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能: 轮廓缩进
|
||||||
|
// * points: 轮廓点集
|
||||||
|
// * center: 围绕center点缩进
|
||||||
|
// * indent: 缩进像素
|
||||||
|
// */
|
||||||
|
// void polyIndent(std::vector<cv::Point>& points, const cv::Point& center, int indent);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能: 二值化,能够处理彩色和灰度图像。src为彩色图像时,灰度图取三个通道的最大值
|
||||||
|
// * src: 源图
|
||||||
|
// * dst: 目标图
|
||||||
|
// * thre: 阈值
|
||||||
|
// */
|
||||||
|
// void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能: 彩色转灰度,灰度图取三个通道的最大值
|
||||||
|
// * src: 源图
|
||||||
|
// * 返回值: 灰度图
|
||||||
|
// */
|
||||||
|
// cv::Mat transforColor(const cv::Mat& src);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能: 获取点的仿射变换
|
||||||
|
// * p: 原点
|
||||||
|
// * warp_mat: 仿射变换系数矩阵
|
||||||
|
// * 返回值: 变换后的点
|
||||||
|
// */
|
||||||
|
// cv::Point warpPoint(const cv::Point& p, const cv::Mat& warp_mat);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能: 点到点距离
|
||||||
|
// * p1: 点1
|
||||||
|
// * p2: 点2
|
||||||
|
// * 返回值: 点到点距离
|
||||||
|
// */
|
||||||
|
// int distanceP2P(const cv::Point& p1, const cv::Point& p2);
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * 功能: 点到直线距离
|
||||||
|
// * p: 点
|
||||||
|
// * l1: 直线端点1
|
||||||
|
// * l2: 直线端点2
|
||||||
|
// * 返回值: 点到直线距离
|
||||||
|
// */
|
||||||
|
// float distanceP2L(const cv::Point& p, const cv::Point& l1, const cv::Point& l2);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #endif // !IMAGE_PROCESS_C_H
|
|
@ -0,0 +1,43 @@
|
||||||
|
// #include "ImageStitch.h"
|
||||||
|
// #include <vector>
|
||||||
|
// using namespace cv;
|
||||||
|
|
||||||
|
// ImageStitch::ImageStitch(int pixtype, int width, int heigth) : m_pixtype(pixtype),
|
||||||
|
// m_width(width),
|
||||||
|
// m_height(heigth)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ImageStitch::~ImageStitch()
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat ImageStitch::GetStitchImage(cv::Mat mat)
|
||||||
|
// {
|
||||||
|
// //cv::imwrite("orgmat.jpg",mat);
|
||||||
|
// cv::Mat dst;
|
||||||
|
// cv::Mat ch_mats[3];
|
||||||
|
// int dstwidth, dstheight;
|
||||||
|
// dstwidth = m_width * 3;
|
||||||
|
// dstheight = m_height / 3;
|
||||||
|
// if (m_pixtype == IMAGE_COLOR)
|
||||||
|
// {
|
||||||
|
// //mat = cv::Mat(m_height / 3, m_width * 9, CV_8UC1, imgdata);
|
||||||
|
// dst = cv::Mat(dstheight, dstwidth, CV_8UC3);
|
||||||
|
// cv::Mat mat1 = mat(cv::Rect(m_width * 3 * 1, 0, m_width * 3, m_height / 3)); //R 对应红通道
|
||||||
|
// cv::Mat mat2 = mat(cv::Rect(m_width * 3 * 2, 0, m_width * 3, m_height / 3)); //G 对应绿通道
|
||||||
|
// cv::Mat mat3 = mat(cv::Rect(m_width * 3 * 0, 0, m_width * 3, m_height / 3)); //B 对应蓝通道
|
||||||
|
// ch_mats[0] = mat1;
|
||||||
|
// ch_mats[1] = mat2;
|
||||||
|
// ch_mats[2] = mat3;
|
||||||
|
// cv::merge(ch_mats, 3, dst);
|
||||||
|
// for (int i = 0; i < 3; i++)
|
||||||
|
// ch_mats[i].release();
|
||||||
|
// LOG("merge mats end \n");
|
||||||
|
// return dst.clone();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// { //gray
|
||||||
|
// return mat;
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -0,0 +1,19 @@
|
||||||
|
// #pragma once
|
||||||
|
// #include <opencv2/opencv.hpp>
|
||||||
|
// #include "scanservices_utils.h"
|
||||||
|
|
||||||
|
// class ImageStitch
|
||||||
|
// {
|
||||||
|
// private:
|
||||||
|
// /* data */
|
||||||
|
// public:
|
||||||
|
// ImageStitch(int pixtype,int width,int heigth);
|
||||||
|
// ~ImageStitch();
|
||||||
|
// cv::Mat GetStitchImage(cv::Mat mat);
|
||||||
|
// private:
|
||||||
|
// int m_pixtype;
|
||||||
|
// int m_width;
|
||||||
|
// int m_height;
|
||||||
|
// cv::Mat m_mat;
|
||||||
|
// };
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
// #include "Jpegcompress.h"
|
||||||
|
// #include <string>
|
||||||
|
|
||||||
|
// JpegCompress::JpegCompress(int quality):tjInstance(NULL)
|
||||||
|
// ,m_quality(quality)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// JpegCompress::~JpegCompress()
|
||||||
|
// {
|
||||||
|
// tjDestroy(tjInstance);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// HG_JpegCompressInfo JpegCompress::GetCompressedImg(cv::Mat& mat)
|
||||||
|
// {
|
||||||
|
// HG_JpegCompressInfo info={0};
|
||||||
|
// if(mat.empty())
|
||||||
|
// {
|
||||||
|
// LOG("JpegCompress Empty Mat! warnning !!!!\n");
|
||||||
|
// return info;
|
||||||
|
// }
|
||||||
|
// tjInstance = tjInitCompress();
|
||||||
|
// int outSubsamp;
|
||||||
|
// int flags = 0;
|
||||||
|
// int pixelFormat;
|
||||||
|
// if (mat.channels() == 1)
|
||||||
|
// {
|
||||||
|
// outSubsamp = TJSAMP_GRAY;
|
||||||
|
// pixelFormat = TJPF_GRAY;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// pixelFormat = TJPF_RGB;
|
||||||
|
// outSubsamp = TJSAMP_444;
|
||||||
|
// }
|
||||||
|
// //std::chrono::steady_clock::time_point _start = std::chrono::steady_clock::now();
|
||||||
|
// //LOG("image rows= %d cols= %d pixelFormat= %d \n",mat.rows,mat.cols,pixelFormat);
|
||||||
|
// tjCompress2(tjInstance, mat.data, mat.cols, 0, mat.rows, pixelFormat,
|
||||||
|
// &info.pJpegData, (long unsigned int*)&info.DataLength, outSubsamp, m_quality, flags);
|
||||||
|
|
||||||
|
// //LOG("jpeg compress done \n");
|
||||||
|
// return info;
|
||||||
|
// }
|
|
@ -0,0 +1,15 @@
|
||||||
|
// #pragma once
|
||||||
|
// #include <turbojpeg.h>
|
||||||
|
// #include <opencv2/opencv.hpp>
|
||||||
|
// #include "scanservices_utils.h"
|
||||||
|
|
||||||
|
// class JpegCompress
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// JpegCompress(int quality=80);
|
||||||
|
// ~JpegCompress();
|
||||||
|
// HG_JpegCompressInfo GetCompressedImg(cv::Mat& mat);
|
||||||
|
// private:
|
||||||
|
// tjhandle tjInstance;
|
||||||
|
// int m_quality;
|
||||||
|
// };
|
|
@ -0,0 +1,286 @@
|
||||||
|
#include "JsonConfig.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#define SCAN_INFO_TITLE "ScanInfo"
|
||||||
|
#define SCAN_TOTAL "TotalScanned"
|
||||||
|
#define SCAN_ROLLERNUM "RollerNum"
|
||||||
|
#define SCAN_CUONUM "CuoNum"
|
||||||
|
#define SCAN_JAMINNUM "JamInNum"
|
||||||
|
#define SCAN_JAMOUTNUM "JamOutNum"
|
||||||
|
#define SCAN_DOUNUM "DoubleNum"
|
||||||
|
#define SCAN_ERRORNUM "ErrorNum"
|
||||||
|
#define SCAN_SERIALNUM "SerialNum"
|
||||||
|
#define SCAN_FWVERSION "FWVersion"
|
||||||
|
#define SCAN_HRATIO "HRatio"
|
||||||
|
#define SCAN_VRATIO "VRatio"
|
||||||
|
#define SCAN_SLEEPTIME "SleepTime"
|
||||||
|
#define SCAN_TOKEN "ScannerToken"
|
||||||
|
#define SCAN_SPEEDMODE "SpeedMode"
|
||||||
|
#define SCAN_VID "VID"
|
||||||
|
#define SCAN_PID "PID"
|
||||||
|
|
||||||
|
#define TOKEN_DEFAULT " "
|
||||||
|
JsonConfig::JsonConfig()
|
||||||
|
{
|
||||||
|
if (access(SCANNER_SCAN_INFO_PATH, F_OK) == -1) //不存在
|
||||||
|
{
|
||||||
|
ScannerScanInfo defaultinfo = CreateDefaultScanInfo();
|
||||||
|
SaveScanInfo(defaultinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JsonConfig::JsonConfig(ConfigType type) : m_cfgType(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonConfig::~JsonConfig()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// bool JsonConfig::ReadParam(FPGAConfigParam ¶m)
|
||||||
|
// {
|
||||||
|
// bool ret = false;
|
||||||
|
// if (access(cfgPaths[m_cfgType].c_str(), F_OK) == -1)
|
||||||
|
// {
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
// std::ifstream i(cfgPaths[m_cfgType]);
|
||||||
|
// json j;
|
||||||
|
// i >> j;
|
||||||
|
// auto &jobject = j[cfgPrefix[m_cfgType]];
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "ExposureF"].get_to(param.ExposureF);
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "ExposureB"].get_to(param.ExposureB);
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "GainF"].get_to(param.GainF);
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "GainB"].get_to(param.GainB);
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "OffsetF"].get_to(param.OffsetF);
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "OffsetB"].get_to(param.OffsetB);
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void JsonConfig::WriteParam(FPGAConfigParam &t_param)
|
||||||
|
// {
|
||||||
|
// FPGAConfigParam param;
|
||||||
|
// if (access(cfgPaths[m_cfgType].c_str(), F_OK) == -1)
|
||||||
|
// {
|
||||||
|
// LOG("Not found config %s \n", cfgPaths[m_cfgType].c_str());
|
||||||
|
// param = CreateDefault();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// param = t_param;
|
||||||
|
|
||||||
|
// LOG("start save %s \n", cfgPaths[m_cfgType].c_str());
|
||||||
|
// json m_json;
|
||||||
|
// auto &jobject = m_json[cfgPrefix[m_cfgType]];
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "ExposureF"] = {param.ExposureF[0], param.ExposureF[1], param.ExposureF[2]};
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "ExposureB"] = {param.ExposureB[0], param.ExposureB[1], param.ExposureB[2]};
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "GainF"] = {param.GainF[0], param.GainF[1], param.GainF[2], param.GainF[3], param.GainF[4], param.GainF[5]};
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "GainB"] = {param.GainB[0], param.GainB[1], param.GainB[2], param.GainB[3], param.GainB[4], param.GainB[5]};
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "OffsetF"] = {param.OffsetF[0], param.OffsetF[1], param.OffsetF[2], param.OffsetF[3], param.OffsetF[4], param.OffsetF[5]};
|
||||||
|
// jobject[cfgPrefix[m_cfgType] + "OffsetB"] = {param.OffsetB[0], param.OffsetB[1], param.OffsetB[2], param.OffsetB[3], param.OffsetB[4], param.OffsetB[5]};
|
||||||
|
// std::ofstream o(cfgPaths[m_cfgType]);
|
||||||
|
// o << std::setw(4) << m_json << std::endl;
|
||||||
|
// LOG("save config %s down \n", cfgPaths[m_cfgType].c_str());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// FPGAConfigParam JsonConfig::CreateDefault()
|
||||||
|
// {
|
||||||
|
// std::string savePath = cfgPaths[m_cfgType];
|
||||||
|
// FPGAConfigParam param = {0};
|
||||||
|
// for (size_t i = 0; i < 3; i++)
|
||||||
|
// {
|
||||||
|
// param.ExposureF[i] = 259;
|
||||||
|
// param.ExposureB[i] = 238;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < 6; i++)
|
||||||
|
// {
|
||||||
|
// param.GainB[i] = 30;
|
||||||
|
// param.GainF[i] = 30;
|
||||||
|
// param.OffsetB[i] = param.OffsetF[i] = 119;
|
||||||
|
// }
|
||||||
|
// return param;
|
||||||
|
// }
|
||||||
|
|
||||||
|
ScannerScanInfo JsonConfig::CreateDefaultScanInfo()
|
||||||
|
{
|
||||||
|
ScannerScanInfo info;
|
||||||
|
info.CuoNum = 0;
|
||||||
|
info.DoubleNum = 0;
|
||||||
|
info.ErrorNum = 0;
|
||||||
|
info.JamInNum = 0;
|
||||||
|
info.JamOutNum = 0;
|
||||||
|
info.FWVersion = FWVERSION;
|
||||||
|
info.SerialNum = SERIALNUM;
|
||||||
|
info.TotalScanned = 0;
|
||||||
|
info.RollerNum = 0;
|
||||||
|
info.HRatio = 1065353216;//(=(float)1.0)
|
||||||
|
info.VRatio = 1065353216;
|
||||||
|
info.SleepTime=3600;
|
||||||
|
info.Token=TOKEN_DEFAULT;
|
||||||
|
info.SpeedMode = 4;
|
||||||
|
l_it = mapFradme_SP.find(info.SpeedMode);
|
||||||
|
info.FWVersion = l_it->second.FWVERSIO;
|
||||||
|
info.VID = 0x3072;
|
||||||
|
#ifdef G400
|
||||||
|
info.PID = 0x0400;
|
||||||
|
#else
|
||||||
|
info.PID = 0x0300;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScannerScanInfo JsonConfig::GetScanInfo()
|
||||||
|
{
|
||||||
|
ScannerScanInfo info;
|
||||||
|
if (access(SCANNER_SCAN_INFO_PATH, F_OK) != 0)
|
||||||
|
{
|
||||||
|
printf("/usr/local/huago/jsonconfig.json do not exist!\n");
|
||||||
|
info = CreateDefaultScanInfo();
|
||||||
|
SaveScanInfo(info);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
std::ifstream i(SCANNER_SCAN_INFO_PATH);
|
||||||
|
auto pos = i.tellg();
|
||||||
|
i.seekg(0, ios::end);
|
||||||
|
cout << "file length =" << i.tellg() << endl;
|
||||||
|
if(i.tellg()<=2)
|
||||||
|
{
|
||||||
|
printf("/usr/local/huago/jsonconfig.json file size < 2!\n");
|
||||||
|
info = CreateDefaultScanInfo();
|
||||||
|
SaveScanInfo(info);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
json j;
|
||||||
|
i.seekg(pos);
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> m_c(m_lock);
|
||||||
|
i >> j;
|
||||||
|
i.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &jobject = j[SCAN_INFO_TITLE];
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_TOTAL))
|
||||||
|
jobject[SCAN_TOTAL].get_to(info.TotalScanned);
|
||||||
|
else
|
||||||
|
info.TotalScanned = 0;
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_ROLLERNUM))
|
||||||
|
jobject[SCAN_ROLLERNUM].get_to(info.RollerNum);
|
||||||
|
else
|
||||||
|
info.RollerNum = 0;
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_CUONUM))
|
||||||
|
jobject[SCAN_CUONUM].get_to(info.CuoNum);
|
||||||
|
else
|
||||||
|
info.CuoNum = 0;
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_JAMINNUM))
|
||||||
|
jobject[SCAN_JAMINNUM].get_to(info.JamInNum);
|
||||||
|
else
|
||||||
|
info.JamInNum = 0;
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_JAMOUTNUM))
|
||||||
|
jobject[SCAN_JAMOUTNUM].get_to(info.JamOutNum);
|
||||||
|
else
|
||||||
|
info.JamOutNum = 0;
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_DOUNUM))
|
||||||
|
jobject[SCAN_DOUNUM].get_to(info.DoubleNum);
|
||||||
|
else
|
||||||
|
info.DoubleNum = 0;
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_ERRORNUM))
|
||||||
|
jobject[SCAN_ERRORNUM].get_to(info.ErrorNum);
|
||||||
|
else
|
||||||
|
info.ErrorNum = 0;
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_SERIALNUM))
|
||||||
|
jobject[SCAN_SERIALNUM].get_to(info.SerialNum);
|
||||||
|
else
|
||||||
|
info.SerialNum = SERIALNUM;
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_FWVERSION))
|
||||||
|
jobject[SCAN_FWVERSION].get_to(info.FWVersion);
|
||||||
|
else
|
||||||
|
info.FWVersion = l_it->second.FWVERSIO;
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_HRATIO))
|
||||||
|
jobject[SCAN_HRATIO].get_to(info.HRatio);
|
||||||
|
else
|
||||||
|
info.HRatio = 1065353216;//默认 1.0f
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_VRATIO))
|
||||||
|
jobject[SCAN_VRATIO].get_to(info.VRatio);
|
||||||
|
else
|
||||||
|
info.VRatio = 1065353216;//默认 1.0f
|
||||||
|
|
||||||
|
if (jobject.contains(SCAN_SLEEPTIME))
|
||||||
|
jobject[SCAN_SLEEPTIME].get_to(info.SleepTime);
|
||||||
|
else
|
||||||
|
info.SleepTime = 3600;//默认 1.0f
|
||||||
|
|
||||||
|
if(jobject.contains(SCAN_TOKEN))
|
||||||
|
jobject[SCAN_TOKEN].get_to(info.Token);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.Token=TOKEN_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(jobject.contains(SCAN_SPEEDMODE))
|
||||||
|
jobject[SCAN_SPEEDMODE].get_to(info.SpeedMode);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.SpeedMode = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(jobject.contains(SCAN_VID))
|
||||||
|
jobject[SCAN_VID].get_to(info.VID);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.VID = 0x3072;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(jobject.contains(SCAN_PID))
|
||||||
|
jobject[SCAN_PID].get_to(info.PID);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef G400
|
||||||
|
info.PID = 0x0400;
|
||||||
|
#else
|
||||||
|
info.PID = 0x0300;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonConfig::SaveScanInfo(const ScannerScanInfo &info)
|
||||||
|
{
|
||||||
|
json m_json;
|
||||||
|
auto &jobject = m_json[SCAN_INFO_TITLE];
|
||||||
|
jobject[SCAN_TOTAL] = info.TotalScanned;
|
||||||
|
jobject[SCAN_ROLLERNUM] = info.RollerNum;
|
||||||
|
jobject[SCAN_CUONUM] = info.CuoNum;
|
||||||
|
jobject[SCAN_JAMINNUM] = info.JamInNum;
|
||||||
|
jobject[SCAN_JAMOUTNUM] = info.JamOutNum;
|
||||||
|
jobject[SCAN_DOUNUM] = info.DoubleNum;
|
||||||
|
jobject[SCAN_ERRORNUM] = info.ErrorNum;
|
||||||
|
jobject[SCAN_SERIALNUM] = info.SerialNum;
|
||||||
|
jobject[SCAN_FWVERSION] = info.FWVersion;
|
||||||
|
jobject[SCAN_HRATIO]= info.HRatio;
|
||||||
|
jobject[SCAN_VRATIO] = info.VRatio;
|
||||||
|
jobject[SCAN_SLEEPTIME] = info.SleepTime;
|
||||||
|
jobject[SCAN_TOKEN] = info.Token;
|
||||||
|
jobject[SCAN_SPEEDMODE] = info.SpeedMode;
|
||||||
|
jobject[SCAN_VID] = info.VID;
|
||||||
|
jobject[SCAN_PID] = info.PID;
|
||||||
|
std::lock_guard<std::mutex> m_c(m_lock);
|
||||||
|
std::ofstream o(SCANNER_SCAN_INFO_PATH);
|
||||||
|
//std::cout<<m_json<<std::endl;
|
||||||
|
o << std::setw(4) << m_json << std::endl;
|
||||||
|
o.close();
|
||||||
|
o.flush();
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#pragma once
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "json.hpp"
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#define SCANNER_SCAN_INFO_PATH "/usr/local/huago/jsonconfig.json"
|
||||||
|
using namespace std;
|
||||||
|
using json = nlohmann::json;
|
||||||
|
class JsonConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class ConfigType
|
||||||
|
{
|
||||||
|
Color_Flat,
|
||||||
|
Color_Correct,
|
||||||
|
Gray_Flat,
|
||||||
|
Gray_Correct
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
map<ConfigType,string> cfgPaths={
|
||||||
|
{ConfigType::Color_Flat,"/usr/local/etc/huago/Color_Flat.json"},
|
||||||
|
{ConfigType::Color_Correct,"/usr/local/etc/huago/Color_Correct.json"},
|
||||||
|
{ConfigType::Gray_Flat,"/usr/local/etc/huago/Gray_Flat.json"},
|
||||||
|
{ConfigType::Gray_Correct,"/usr/local/etc/huago/Gray_Correct.json"}
|
||||||
|
};
|
||||||
|
|
||||||
|
map<ConfigType,string> cfgPrefix={
|
||||||
|
{ConfigType::Color_Flat,"Color_Flat"},
|
||||||
|
{ConfigType::Color_Correct,"Color_Correct"},
|
||||||
|
{ConfigType::Gray_Flat,"Gray_Flat"},
|
||||||
|
{ConfigType::Gray_Correct,"Gray_Correct"}
|
||||||
|
};
|
||||||
|
ConfigType m_cfgType;
|
||||||
|
public:
|
||||||
|
JsonConfig();
|
||||||
|
JsonConfig(ConfigType type);
|
||||||
|
~JsonConfig();
|
||||||
|
/*
|
||||||
|
*若返回false 则表示文件不存在或文件读取失败
|
||||||
|
*/
|
||||||
|
// bool ReadParam(FPGAConfigParam& param);
|
||||||
|
|
||||||
|
// void WriteParam(FPGAConfigParam& t_param);
|
||||||
|
|
||||||
|
ScannerScanInfo GetScanInfo();
|
||||||
|
map<int, sp_COLOR_or_GRAY >::iterator l_it;
|
||||||
|
void SaveScanInfo(const ScannerScanInfo& info);
|
||||||
|
private:
|
||||||
|
//FPGAConfigParam CreateDefault();
|
||||||
|
std::mutex m_lock;
|
||||||
|
ScannerScanInfo CreateDefaultScanInfo();
|
||||||
|
};
|
|
@ -0,0 +1,192 @@
|
||||||
|
#include "Keyboard.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#define KEYCODE_POWER 62
|
||||||
|
#define KEYCODE_START 60
|
||||||
|
#define KEYCODE_STOP 61
|
||||||
|
|
||||||
|
namespace huagao
|
||||||
|
{
|
||||||
|
|
||||||
|
Keyboard::Keyboard(std::function<void(const int)> buttonevent)
|
||||||
|
{
|
||||||
|
m_event = buttonevent;
|
||||||
|
mInputFd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyboard::~Keyboard()
|
||||||
|
{
|
||||||
|
b_run = false;
|
||||||
|
if (pollthread.joinable())
|
||||||
|
pollthread.join();
|
||||||
|
if (mInputFd > 0)
|
||||||
|
{
|
||||||
|
::close(mInputFd);
|
||||||
|
}
|
||||||
|
::close(mEpId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keyboard::init()
|
||||||
|
{
|
||||||
|
mEpId = epoll_create(1);
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
std::string ev_name[] = {
|
||||||
|
"EV_SYN",
|
||||||
|
"EV_KEY",
|
||||||
|
"EV_REL",
|
||||||
|
"EV_ABS",
|
||||||
|
"EV_MSC",
|
||||||
|
"EV_SW",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"NULL",
|
||||||
|
"EV_LED",
|
||||||
|
"EV_LND",
|
||||||
|
"NULL",
|
||||||
|
"EV_REP",
|
||||||
|
"EV_FF",
|
||||||
|
"EV_PWR",
|
||||||
|
};
|
||||||
|
if (mInputFd == -1)
|
||||||
|
{
|
||||||
|
LOG("open kd device or mouse fail! \n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ev.data.fd = mInputFd;
|
||||||
|
ev.events = EPOLLIN | EPOLLET;
|
||||||
|
int ret = epoll_ctl(mEpId, EPOLL_CTL_ADD, mInputFd, &ev);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
LOG("add kd device in epoll fail! \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = ioctl(mInputFd, EVIOCGID, &id);
|
||||||
|
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
LOG("bustype = 0x%x\n", id.bustype);
|
||||||
|
LOG("vendor = 0x%x\n", id.vendor);
|
||||||
|
LOG("product = 0x%x\n", id.product);
|
||||||
|
LOG("version = 0x%x\n", id.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(mInputFd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
LOG("support ev type : ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1 << bit))
|
||||||
|
LOG("%s ", ev_name[i * 8 + bit].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG("\n");
|
||||||
|
}
|
||||||
|
b_run = true;
|
||||||
|
pollthread = std::thread(&Keyboard::poll, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keyboard::poll()
|
||||||
|
{
|
||||||
|
int re = 0;
|
||||||
|
while (b_run)
|
||||||
|
{
|
||||||
|
re = epoll_wait(mEpId, events, MAX_EVENTS, 1000);
|
||||||
|
for (int i = 0; i < re; ++i)
|
||||||
|
{
|
||||||
|
if (events[i].events & EPOLLIN)
|
||||||
|
{
|
||||||
|
LOG("poll\n");
|
||||||
|
doInput(events + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
re = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long time_pressed_sec;
|
||||||
|
long time_pressed_usec;
|
||||||
|
|
||||||
|
void Keyboard::doInput(const epoll_event *ev)
|
||||||
|
{
|
||||||
|
ssize_t resize = 0;
|
||||||
|
ssize_t n = 0;
|
||||||
|
struct input_event input_ev;
|
||||||
|
while ((resize = read(ev->data.fd, buffer + n, sizeof(struct input_event) - n)) > 0)
|
||||||
|
{
|
||||||
|
n += resize;
|
||||||
|
if (n == sizeof(input_event))
|
||||||
|
{
|
||||||
|
memcpy((void *)(&input_ev), buffer, sizeof(input_event));
|
||||||
|
LOG("keyboard type=%d; code=%d; value=%d, sec=%ld, usec=%ld\n", (int)input_ev.type,
|
||||||
|
(int)input_ev.code, (int)input_ev.value, input_ev.time.tv_sec, input_ev.time.tv_usec);
|
||||||
|
if (input_ev.type == 0)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (input_ev.value == 1)
|
||||||
|
{
|
||||||
|
LOG("pressed....\n");
|
||||||
|
time_pressed_sec = (long)input_ev.time.tv_sec;
|
||||||
|
time_pressed_usec = (long)input_ev.time.tv_usec;
|
||||||
|
n = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LOG("keyboard press tiem sec=%ld, usec=%ld\n", time_pressed_sec, time_pressed_usec);
|
||||||
|
long delay = (input_ev.time.tv_usec - time_pressed_usec) / 1000;
|
||||||
|
delay = delay + (input_ev.time.tv_sec - time_pressed_sec) * 1000;
|
||||||
|
LOG("press delay:%ld\n", delay);
|
||||||
|
switch (input_ev.code)
|
||||||
|
{
|
||||||
|
case KEYCODE_POWER:
|
||||||
|
if (delay >= 1000)
|
||||||
|
{
|
||||||
|
if (!b_lowpwoer) //未进入低功耗 则触发低功耗模式
|
||||||
|
{
|
||||||
|
b_lowpwoer = !b_lowpwoer;
|
||||||
|
m_event(2);
|
||||||
|
}
|
||||||
|
else //已进入低功耗模式
|
||||||
|
b_lowpwoer = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b_lowpwoer = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEYCODE_START:
|
||||||
|
m_event(0);
|
||||||
|
break;
|
||||||
|
case KEYCODE_STOP:
|
||||||
|
LOG("stop KEYCODE_STOP pressed!\n");
|
||||||
|
m_event(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace huagao
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <time.h>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <functional>
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
|
||||||
|
static const char kDevInput[] = "/dev/input/event0";
|
||||||
|
|
||||||
|
#define MAX_EVENTS 10
|
||||||
|
namespace huagao
|
||||||
|
{
|
||||||
|
|
||||||
|
class Keyboard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Keyboard(std::function<void(const int)> buttonevent);
|
||||||
|
~Keyboard();
|
||||||
|
void init();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int mInputFd;
|
||||||
|
int mEpId;
|
||||||
|
struct epoll_event ev;
|
||||||
|
struct epoll_event events[MAX_EVENTS];
|
||||||
|
std::thread pollthread;
|
||||||
|
char buffer[sizeof(input_event)];
|
||||||
|
void poll();
|
||||||
|
void doInput(const epoll_event *ev);
|
||||||
|
bool b_run =false;
|
||||||
|
bool b_lowpwoer = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void(const int)> m_event;
|
||||||
|
};
|
||||||
|
} // namespace huagao
|
|
@ -0,0 +1,36 @@
|
||||||
|
#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);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
#include "DevUtil.h"
|
||||||
|
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "MemoryInfo.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
MemoryInfo* MemoryInfo::m_pInstance=nullptr;
|
||||||
|
MemoryInfo::Garbo MemoryInfo::garbo;
|
||||||
|
|
||||||
|
MemoryInfo::MemoryInfo(/* args */)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// MemoryInfo::~MemoryInfo()
|
||||||
|
// {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
MemoryInfo* MemoryInfo::GetInstance()
|
||||||
|
{
|
||||||
|
if(m_pInstance==nullptr)
|
||||||
|
{
|
||||||
|
m_pInstance= new MemoryInfo();
|
||||||
|
}
|
||||||
|
return m_pInstance;
|
||||||
|
}
|
||||||
|
float MemoryInfo::GetMemoryUsed()
|
||||||
|
{
|
||||||
|
float ret=0.0f;
|
||||||
|
Mem_info info;
|
||||||
|
getMemInfo(info);
|
||||||
|
if(info.total!=0)
|
||||||
|
ret=(100.0 * (info.total - info.available) / info.total);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryInfo::getMemInfo(Mem_info& info)
|
||||||
|
{
|
||||||
|
FILE* fpMemInfo = fopen("/proc/meminfo", "r");
|
||||||
|
if (NULL == fpMemInfo)
|
||||||
|
{
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
int value;
|
||||||
|
char name[1024];
|
||||||
|
char line[1024];
|
||||||
|
int nFiledNumber = 2;
|
||||||
|
int nMemberNumber = 5;
|
||||||
|
while (fgets(line, sizeof(line) - 1, fpMemInfo))
|
||||||
|
{
|
||||||
|
if (sscanf(line, "%s%u", name, &value) != nFiledNumber)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (0 == strcmp(name, "MemTotal:"))
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
info.total = value;
|
||||||
|
}
|
||||||
|
else if (0 == strcmp(name, "MemFree:"))
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
info.free = value;
|
||||||
|
}
|
||||||
|
else if (0 == strcmp(name, "MemAvailable:"))
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
info.available = value;
|
||||||
|
}
|
||||||
|
else if (0 == strcmp(name, "Buffers:"))
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
info.buffers = value;
|
||||||
|
}
|
||||||
|
else if (0 == strcmp(name, "Cached:"))
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
info.cached = value;
|
||||||
|
}
|
||||||
|
if (i == nMemberNumber)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fpMemInfo);
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class MemoryInfo
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct MEM_INFO
|
||||||
|
{
|
||||||
|
unsigned int total;
|
||||||
|
unsigned int free;
|
||||||
|
unsigned int buffers;
|
||||||
|
unsigned int cached;
|
||||||
|
unsigned int swap_cached;
|
||||||
|
unsigned int swap_total;
|
||||||
|
unsigned int swap_free;
|
||||||
|
unsigned int available;
|
||||||
|
};
|
||||||
|
typedef struct MEM_INFO Mem_info;
|
||||||
|
MemoryInfo(/* args */);
|
||||||
|
~MemoryInfo(){}
|
||||||
|
MemoryInfo& operator=(const MemoryInfo &);
|
||||||
|
void getMemInfo(Mem_info& info);
|
||||||
|
public:
|
||||||
|
static MemoryInfo* GetInstance();
|
||||||
|
float GetMemoryUsed();
|
||||||
|
private:
|
||||||
|
class Garbo
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
~Garbo()
|
||||||
|
{
|
||||||
|
if(MemoryInfo::m_pInstance!=nullptr)
|
||||||
|
{
|
||||||
|
delete MemoryInfo::m_pInstance;
|
||||||
|
MemoryInfo::m_pInstance=nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static MemoryInfo* m_pInstance;
|
||||||
|
static Garbo garbo;
|
||||||
|
};
|
|
@ -0,0 +1,141 @@
|
||||||
|
#include "Motor.h"
|
||||||
|
#include "DevUtil.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
#include <exception>
|
||||||
|
#include "utilsfunc.h"
|
||||||
|
#include "MotorConfig.h"
|
||||||
|
|
||||||
|
#define ZZ_PWM 3
|
||||||
|
#define CZ_PWM 2
|
||||||
|
|
||||||
|
struct MotorMode
|
||||||
|
{
|
||||||
|
int mod0 : 1;
|
||||||
|
int mod1 : 1;
|
||||||
|
int mod2 : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// const MotorPorts motorPorts_Zouzhi = {.reset = ZouZhiMotor_Reset, .sleep = ZouZhiMotor_Sleep, .enable = ZouZhiMotor_Enable, .dir = ZouZhiMotor_Direction, .decay = ZouZhiMotor_Decay, .home = ZouZhiMotor_Home, .fault = ZouZhiMotor_Fault, .mode0 = ZouZhiMotor_Mode0, .mode1 = ZouZhiMotor_Mode1, .mode2 = ZouZhiMotor_Mode2, .pwm = ZZ_PWM};
|
||||||
|
|
||||||
|
// const MotorPorts motorPorts_Cuozhi = {.reset = CuoZhiMotor_Reset, .sleep = CuoZhiMotor_Sleep, .enable = CuoZhiMotor_Enable, .dir = CuoZhiMotor_Direction, .decay = CuoZhiMotor_Decay, .home = CuoZhiMotor_Home, .fault = CuoZhiMotor_Fault, .mode0 = CuoZhiMotor_Mode0, .mode1 = CuoZhiMotor_Mode1, .mode2 = CuoZhiMotor_Mode2, .pwm = CZ_PWM};
|
||||||
|
const MotorPorts motorPorts_Zouzhi = { .power = PIN_PORT_7010::MOTOR_POWER_1,
|
||||||
|
.reset = PIN_PORT_7010::ZOUZHI_PIN_RESET,
|
||||||
|
.sleep = PIN_PORT_7010::ZOUZHI_PIN_SLEEP,
|
||||||
|
.enable = PIN_PORT_7010::ZOUZHI_PIN_ENABEL,
|
||||||
|
.dir = PIN_PORT_7010::ZOUZHI_PIN_DIR,
|
||||||
|
.pwm = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
const MotorPorts motorPorts_Cuozhi = { .power =PIN_PORT_7010::MOTOR_POWER_2,
|
||||||
|
.reset = PIN_PORT_7010::CUOZHI_PIN_RESET,
|
||||||
|
.sleep = PIN_PORT_7010::CUOZHI_PIN_SLEEP,
|
||||||
|
.enable = PIN_PORT_7010::CUOZHI_PIN_ENABEL,
|
||||||
|
.dir = PIN_PORT_7010::CUOZHI_PIN_DIR,
|
||||||
|
.pwm = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<int> speedup_cfg(int finalPeriod, int Fmin, int stepnum, int a, int offset, int finalDelay)
|
||||||
|
{
|
||||||
|
std::vector<int> freqs;
|
||||||
|
int period = 0;
|
||||||
|
double delay = ((double)finalDelay) / 1000000.0;
|
||||||
|
double b = stepnum * delay;
|
||||||
|
for (int i = 0; i < stepnum; i++)
|
||||||
|
{
|
||||||
|
period = (int)(finalPeriod + (Fmin - finalPeriod) / (1 + exp(-a * b + offset)));
|
||||||
|
b = b - delay;
|
||||||
|
freqs.push_back(period);
|
||||||
|
}
|
||||||
|
return freqs;
|
||||||
|
}
|
||||||
|
|
||||||
|
//GpioOut Motor::powerPin(MotorPower);
|
||||||
|
|
||||||
|
Motor::Motor(MotorPorts motorPorts):sleepPin(motorPorts.sleep),
|
||||||
|
resetPin(motorPorts.reset),
|
||||||
|
enablePin(motorPorts.enable),
|
||||||
|
dirPin(motorPorts.dir),
|
||||||
|
pwm(motorPorts.pwm),
|
||||||
|
motor_power(motorPorts.power)
|
||||||
|
{
|
||||||
|
sleepPin.setDirection(Gpio::out);
|
||||||
|
resetPin.setDirection(Gpio::out);
|
||||||
|
enablePin.setDirection(Gpio::out);
|
||||||
|
dirPin.setDirection(Gpio::out);
|
||||||
|
motor_power.setDirection(Gpio::out);
|
||||||
|
|
||||||
|
motor_power.setValue(Gpio::High); //0:关闭电机电源 1:开启电机电源 //默认一直开启
|
||||||
|
//默认设置 1 1 1
|
||||||
|
resetPin.setValue(Gpio::High); //0:重启 1:电机不重启
|
||||||
|
sleepPin.setValue(Gpio::High); //0:电机停止转动 1:电机开始转动
|
||||||
|
enablePin.setValue(Gpio::High); //0:电机芯片打开电源 1:电机芯片关闭电源
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Motor::~Motor()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
if (m_mtconfig.get())
|
||||||
|
m_mtconfig.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Motor::start(std ::vector<int> &delay_s, const MotorSpeedParam &msp)
|
||||||
|
{
|
||||||
|
enablePin.setValue(Gpio::Low);
|
||||||
|
pwm.enable(true);
|
||||||
|
if (!delay_s.empty())
|
||||||
|
{
|
||||||
|
std::vector<int>::iterator iter = delay_s.begin();
|
||||||
|
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);
|
||||||
|
//pwm.setFreq((PWM_PERIOD / msp.finalPeriod)/10*10);
|
||||||
|
//printf("\n-----pwm Freq = %d------\n",PWM_PERIOD / msp.finalPeriod/10*10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Motor::start()
|
||||||
|
{
|
||||||
|
enablePin.setValue(Gpio::Low);
|
||||||
|
pwm.enable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Motor::stop()
|
||||||
|
{
|
||||||
|
enablePin.setValue(Gpio::High);
|
||||||
|
pwm.enable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Motor::pause()
|
||||||
|
{
|
||||||
|
pwm.enable(false);
|
||||||
|
enablePin.setValue(Gpio::Low);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Motor::setMode(int mode_input)
|
||||||
|
{
|
||||||
|
// MotorMode *mode = (MotorMode *)&mode_input;
|
||||||
|
// mode0.setValue((Gpio::GpioLevel)mode->mod0);
|
||||||
|
// mode1.setValue((Gpio::GpioLevel)mode->mod1);
|
||||||
|
// mode2.setValue((Gpio::GpioLevel)mode->mod2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Motor::setDirection(int dir)
|
||||||
|
{
|
||||||
|
dirPin.setValue((Gpio::GpioLevel)dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Motor::setSpeed(int value)
|
||||||
|
{
|
||||||
|
pwm.setFreq(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Motor::enablePower(bool bEnable)
|
||||||
|
{
|
||||||
|
LOG("Enable Motor PowerPin %s \n", bEnable ? "true" : "false");
|
||||||
|
//powerPin.setValue((Gpio::GpioLevel)bEnable);
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Gpio.h"
|
||||||
|
#include "Pwm.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <iostream>
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
#include "utilsfunc.h"
|
||||||
|
#include <exception>
|
||||||
|
#include "Motordef.h"
|
||||||
|
#include "MotorConfig.h"
|
||||||
|
|
||||||
|
struct MotorPorts
|
||||||
|
{
|
||||||
|
int power;
|
||||||
|
int reset;
|
||||||
|
int sleep;
|
||||||
|
int enable;
|
||||||
|
int dir;
|
||||||
|
int decay;
|
||||||
|
int home;
|
||||||
|
int fault;
|
||||||
|
int mode0;
|
||||||
|
int mode1;
|
||||||
|
int mode2;
|
||||||
|
int pwm;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern const MotorPorts motorPorts_Zouzhi;
|
||||||
|
extern const MotorPorts motorPorts_Cuozhi;
|
||||||
|
|
||||||
|
class Motor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Motor(MotorPorts motorPorts);
|
||||||
|
virtual ~Motor();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//static GpioOut powerPin;
|
||||||
|
Gpio motor_power;
|
||||||
|
Gpio resetPin;
|
||||||
|
Gpio sleepPin;
|
||||||
|
Gpio enablePin;
|
||||||
|
Gpio dirPin;
|
||||||
|
Pwm pwm;
|
||||||
|
|
||||||
|
std::shared_ptr<MotorConfig> m_mtconfig;
|
||||||
|
SMBType smbtype;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void start(std::vector<int> &delay_s, const MotorSpeedParam &msp);
|
||||||
|
|
||||||
|
virtual void start();
|
||||||
|
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
void pause();
|
||||||
|
|
||||||
|
void setMode(int mode_input);
|
||||||
|
|
||||||
|
void setDirection(int dir);
|
||||||
|
|
||||||
|
void setSpeed(int value);
|
||||||
|
|
||||||
|
static void enablePower(bool bEnable);
|
||||||
|
|
||||||
|
static int isPowerOn()
|
||||||
|
{
|
||||||
|
return 0;//powerPin.getValue();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::vector<int> speedup_cfg(int finalPeriod, int Fmin, int stepnum, int a, int offset, int finalDelay);
|
|
@ -0,0 +1,255 @@
|
||||||
|
#include "MotorConfig.h"
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
MotorConfig::MotorConfig()
|
||||||
|
{
|
||||||
|
initconfigfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
MotorConfig::~MotorConfig()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MotorConfig::GetParams(bool bzouzhi, MTBDType mttype)
|
||||||
|
{
|
||||||
|
std::string j_str;
|
||||||
|
json j;
|
||||||
|
if (mttype == MTBDType::MT_TMC)
|
||||||
|
{
|
||||||
|
std::ifstream i(bzouzhi ? MT_TMC216_ZOU_PATH : MT_TMC216_CUO_PATH);
|
||||||
|
i >> j;
|
||||||
|
j_str = j.dump();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ifstream i(bzouzhi ? MT_DRV888_ZOU_PATH : MT_DRV888_CUO_PATH);
|
||||||
|
i >> j;
|
||||||
|
j_str = j.dump();
|
||||||
|
}
|
||||||
|
return j_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorConfig::SetParams(bool bzouzhi, MTBDType mttype, MotorSpeedParamEx ¶m)
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
auto params = GetMotorSpeedParams(bzouzhi, mttype);
|
||||||
|
for (int i = 0; i < params.size(); i++)
|
||||||
|
{
|
||||||
|
if (params[i].dpi == param.dpi &&
|
||||||
|
params[i].colormode == param.colormode &&
|
||||||
|
params[i].speed == param.speed)
|
||||||
|
{
|
||||||
|
params[i] = param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json j = json::array();
|
||||||
|
|
||||||
|
for (int i = 0; i < params.size(); i++)
|
||||||
|
{
|
||||||
|
json t_j;
|
||||||
|
to_json(params[i], t_j);
|
||||||
|
j.push_back(t_j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mttype == MTBDType::MT_TMC)
|
||||||
|
path = bzouzhi ? MT_TMC216_ZOU_PATH : MT_TMC216_CUO_PATH;
|
||||||
|
else
|
||||||
|
path = bzouzhi ? MT_DRV888_ZOU_PATH : MT_DRV888_CUO_PATH;
|
||||||
|
|
||||||
|
ofstream ofs(path);
|
||||||
|
ofs << std::setw(4) << j << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MotorSpeedParamEx> MotorConfig::GetMotorSpeedParams(bool bzouzhi, MTBDType mttype)
|
||||||
|
{
|
||||||
|
std::vector<MotorSpeedParamEx> ret;
|
||||||
|
if (mttype == MTBDType::MT_TMC)
|
||||||
|
{
|
||||||
|
std::ifstream i(bzouzhi ? MT_TMC216_ZOU_PATH : MT_TMC216_CUO_PATH);
|
||||||
|
json j;
|
||||||
|
i >> j;
|
||||||
|
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
||||||
|
{
|
||||||
|
auto tmv = it.value();
|
||||||
|
MotorSpeedParamEx param;
|
||||||
|
from_json(tmv, param);
|
||||||
|
ret.push_back(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ifstream i(bzouzhi ? MT_DRV888_ZOU_PATH : MT_DRV888_CUO_PATH);
|
||||||
|
json j;
|
||||||
|
i >> j;
|
||||||
|
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
||||||
|
{
|
||||||
|
auto tmv = it.value();
|
||||||
|
MotorSpeedParamEx param;
|
||||||
|
from_json(tmv, param);
|
||||||
|
ret.push_back(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorConfig::initconfigfile()
|
||||||
|
{
|
||||||
|
struct stat buff;
|
||||||
|
for (int s = 0; s < m_jsonpaths.size(); s++)
|
||||||
|
{
|
||||||
|
if (stat(m_jsonpaths[s].c_str(), &buff) != 0) //不存在
|
||||||
|
{
|
||||||
|
{
|
||||||
|
json j = json::array();
|
||||||
|
for (int i = 1; i < 6; i++)//speed mode
|
||||||
|
{
|
||||||
|
MotorSpeedParamEx param;
|
||||||
|
for (int k = 1; k < 4; k++) //dpi
|
||||||
|
{
|
||||||
|
double ratio = k == 1 ? 1 : (k == 2 ? 1.51 : 2.81);
|
||||||
|
param.mt_param.finalPeriod = s >= 2 ? 228000 / 4 *ratio: 228000*ratio; // 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 = 9;
|
||||||
|
param.mt_param.finalDelay = 2500;
|
||||||
|
param.speed = i; // 0 gray 1 color
|
||||||
|
param.dpi = k; // 1 200dpi 2 300dpi 3 600dpi
|
||||||
|
param.mt_param.acceleration_time=0;
|
||||||
|
for (int t = 0; t < 2; t++)//color mode
|
||||||
|
{
|
||||||
|
param.colormode = t;
|
||||||
|
if(t==1&& k== 1) param.sp = 2570;//200 color
|
||||||
|
else if(t==0&& k== 1) param.sp = 8150;//200 gray
|
||||||
|
else if(t==1&& k== 2) param.sp = 1719;//300 color
|
||||||
|
else if(t==0&& k== 2) param.sp = 5452;//300 color
|
||||||
|
else if(t==1&& k== 3) param.sp = 1700;//600 gray
|
||||||
|
else if(t==0&& k== 3) param.sp = 4850;//600 color
|
||||||
|
|
||||||
|
json t_j;
|
||||||
|
to_json(param, t_j);
|
||||||
|
j.push_back(t_j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ofstream ofs(m_jsonpaths[s]);
|
||||||
|
ofs << std::setw(4) << j << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MotorSpeedParamEx> MotorConfig::GetMotorSpeedParams(const std::string &json_str)
|
||||||
|
{
|
||||||
|
std::vector<MotorSpeedParamEx> ret;
|
||||||
|
if (json_str.length())
|
||||||
|
{
|
||||||
|
json j(json_str);
|
||||||
|
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
||||||
|
{
|
||||||
|
auto tmv = it.value();
|
||||||
|
MotorSpeedParamEx param;
|
||||||
|
from_json(tmv, param);
|
||||||
|
ret.push_back(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MotorSpeedParamEx MotorConfig::GetMotorSpeedParam(bool bzouzhi,MTBDType mttype,int speed,int colormmode,int dpi)
|
||||||
|
{
|
||||||
|
MotorSpeedParamEx retparam;
|
||||||
|
auto exparams= GetMotorSpeedParams(bzouzhi,mttype);
|
||||||
|
for(auto &item:exparams)
|
||||||
|
{
|
||||||
|
if(item.colormode==colormmode &&
|
||||||
|
item.dpi==dpi&&
|
||||||
|
item.speed==speed)
|
||||||
|
{
|
||||||
|
retparam = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retparam;
|
||||||
|
}
|
||||||
|
void MotorConfig::to_json(MotorSpeedParamEx ¶m, json &j)
|
||||||
|
{
|
||||||
|
j = json{
|
||||||
|
{"A", param.mt_param.a},
|
||||||
|
{"FINALDELAY", param.mt_param.finalDelay},
|
||||||
|
{"FINALPERIOD", param.mt_param.finalPeriod},
|
||||||
|
{"FMIN", param.mt_param.Fmin},
|
||||||
|
{"OFFSET", param.mt_param.offset},
|
||||||
|
{"STEPNUM", param.mt_param.stepnum},
|
||||||
|
{"DPI", param.dpi},
|
||||||
|
{"COLORMODE", param.colormode},
|
||||||
|
{"ACCELERATIONTIME",param.mt_param.acceleration_time},
|
||||||
|
{"SPEED", param.speed},
|
||||||
|
{"SP",param.sp}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorConfig::from_json(json &j, MotorSpeedParamEx ¶m)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(j.contains("A"))
|
||||||
|
j.at("A").get_to(param.mt_param.a);
|
||||||
|
else
|
||||||
|
param.mt_param.a = 200;
|
||||||
|
|
||||||
|
if(j.contains("FINALDELAY"))
|
||||||
|
j.at("FINALDELAY").get_to(param.mt_param.finalDelay);
|
||||||
|
else
|
||||||
|
param.mt_param.finalDelay=2500;
|
||||||
|
|
||||||
|
if(j.contains("FINALPERIOD"))
|
||||||
|
j.at("FINALPERIOD").get_to(param.mt_param.finalPeriod);
|
||||||
|
else
|
||||||
|
param.mt_param.finalPeriod = 455000;
|
||||||
|
|
||||||
|
if(j.contains("FMIN"))
|
||||||
|
j.at("FMIN").get_to(param.mt_param.Fmin);
|
||||||
|
else
|
||||||
|
param.mt_param.Fmin = 1655000;
|
||||||
|
|
||||||
|
if(j.contains("OFFSET"))
|
||||||
|
j.at("OFFSET").get_to(param.mt_param.offset);
|
||||||
|
else
|
||||||
|
param.mt_param.offset=7;
|
||||||
|
|
||||||
|
if(j.contains("STEPNUM"))
|
||||||
|
j.at("STEPNUM").get_to(param.mt_param.stepnum);
|
||||||
|
else
|
||||||
|
param.mt_param.stepnum=30;
|
||||||
|
|
||||||
|
if(j.contains("DPI"))
|
||||||
|
j.at("DPI").get_to(param.dpi);
|
||||||
|
else
|
||||||
|
param.dpi = 1;
|
||||||
|
|
||||||
|
if(j.contains("COLORMODE"))
|
||||||
|
j.at("COLORMODE").get_to(param.colormode);
|
||||||
|
else
|
||||||
|
param.colormode=1;
|
||||||
|
|
||||||
|
if(j.contains("ACCELERATIONTIME"))
|
||||||
|
j.at("ACCELERATIONTIME").get_to(param.mt_param.acceleration_time);
|
||||||
|
else
|
||||||
|
param.mt_param.acceleration_time=0;
|
||||||
|
|
||||||
|
if(j.contains("SPEED"))
|
||||||
|
j.at("SPEED").get_to(param.speed);
|
||||||
|
else
|
||||||
|
param.speed=4;
|
||||||
|
|
||||||
|
if(j.contains("SP"))
|
||||||
|
j.at("SP").get_to(param.sp);
|
||||||
|
else
|
||||||
|
param.sp=1800;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
#include "json.hpp"
|
||||||
|
#include "Motordef.h"
|
||||||
|
|
||||||
|
using json= nlohmann::json;
|
||||||
|
|
||||||
|
#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:
|
||||||
|
const std::vector<std::string> 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
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
MotorConfig(/* args */);
|
||||||
|
~MotorConfig();
|
||||||
|
std::string GetParams(bool bzouzhi,MTBDType mttype);
|
||||||
|
void SetParams(bool bzouzhi,MTBDType mttype,MotorSpeedParamEx& param);
|
||||||
|
std::vector<MotorSpeedParamEx> GetMotorSpeedParams(bool bzouzhi,MTBDType mttype);
|
||||||
|
std::vector<MotorSpeedParamEx> GetMotorSpeedParams(const std::string& json_str);
|
||||||
|
MotorSpeedParamEx GetMotorSpeedParam(bool bzouzhi,MTBDType mttype,int speed,int colormmode,int dpi);
|
||||||
|
private:
|
||||||
|
void initconfigfile();
|
||||||
|
void to_json(MotorSpeedParamEx& param,json& j);
|
||||||
|
void from_json(json& j,MotorSpeedParamEx& param);
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,120 @@
|
||||||
|
#include "ICapturer.h"
|
||||||
|
#include <thread>
|
||||||
|
#include "autoevent.hpp"
|
||||||
|
#include "CorrectParam.h"
|
||||||
|
#include "IPreproc.h"
|
||||||
|
|
||||||
|
class FpgaComm;
|
||||||
|
class gVideo;
|
||||||
|
class Gpio;
|
||||||
|
class GpioOut;
|
||||||
|
|
||||||
|
class MultiFrameCapture : public ICapturer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct frame_data_info
|
||||||
|
{
|
||||||
|
void* pdata;
|
||||||
|
unsigned int offset;
|
||||||
|
unsigned int total_dst;
|
||||||
|
unsigned int frame_count;
|
||||||
|
};
|
||||||
|
const int FPGA_MAX_HEIGHT_SUP=1048576;
|
||||||
|
//const int FRAME_HEIGHT=2700;
|
||||||
|
int frame_height = 60;
|
||||||
|
int readframe_timeout = 100;
|
||||||
|
unsigned int frame_count;
|
||||||
|
std::shared_ptr<GpioOut> reset_pin; //fpga 逻辑复位以及固件重载初始化。 7010 7/15没有 以防固件跑飞了保证能够不重启就能解决
|
||||||
|
std::shared_ptr<Gpio> fpgaLoad;
|
||||||
|
std::shared_ptr<Gpio> fpga_conf_initn;
|
||||||
|
BlockingQueue<V4L2_DATAINFO_Ex> m_frameinfos;
|
||||||
|
bool b_snap_run;
|
||||||
|
bool b_stop_snap;
|
||||||
|
bool b_end_snap;
|
||||||
|
bool b_imgproc;
|
||||||
|
bool is_size_error;
|
||||||
|
int snaped_index;
|
||||||
|
bool bScanning;
|
||||||
|
std::atomic<int> iImageremain;
|
||||||
|
FPGAConfigParam m_fpgaparam;
|
||||||
|
std::mutex m_mtx_snap;
|
||||||
|
std::mutex m_mtx_snapdone;
|
||||||
|
std::condition_variable m_cv_snap;
|
||||||
|
std::condition_variable m_cv_snapdone;
|
||||||
|
std::shared_ptr<std::thread> m_snap_thread;
|
||||||
|
std::shared_ptr<std::thread> m_imgproc_thread;
|
||||||
|
//std::vector<cv::Mat> m_frames;
|
||||||
|
std::vector<std::shared_ptr<IPreproc>> m_preproclist;
|
||||||
|
std::thread m_correctThread;
|
||||||
|
frame_data_info pimgdata_info;
|
||||||
|
ScannerGlue m_glue;
|
||||||
|
int offsetStep[12];
|
||||||
|
int expStep[2][3];
|
||||||
|
double radio = 1;
|
||||||
|
|
||||||
|
CamZ_Reg_4 reg_;
|
||||||
|
private:
|
||||||
|
void reset_fpga();
|
||||||
|
void reload_fpga();
|
||||||
|
void set_gain(int ix, int val);
|
||||||
|
void set_offset(int ix, int val);
|
||||||
|
void set_expo(int ix, int val);
|
||||||
|
void configFPGAParam(int mode,int dpi);
|
||||||
|
int color();
|
||||||
|
int width();
|
||||||
|
void snaprun();
|
||||||
|
void updatesnapstatus(int papertype);
|
||||||
|
void procimage();
|
||||||
|
void formatStep();
|
||||||
|
bool saveLutImg(int dpi, int mode, bool black);
|
||||||
|
void creatcorrectconfig(int dpi,int mode);
|
||||||
|
void correctcolor(int correctmode);
|
||||||
|
void openDevice(int dpi,int mode);
|
||||||
|
//void myFloodFill(cv::Mat& image, bool isTwoSide);
|
||||||
|
void init_imagedatabuffer();
|
||||||
|
//void update_imgdatainfo(cv::Mat itemmat);
|
||||||
|
void reset_imagedata();
|
||||||
|
|
||||||
|
public:
|
||||||
|
MultiFrameCapture(ScannerGlue glue, std::shared_ptr<FpgaComm> fpga, CISVendor vendor);
|
||||||
|
|
||||||
|
virtual ~MultiFrameCapture();
|
||||||
|
|
||||||
|
virtual void SetParent(void *scanner) override;
|
||||||
|
|
||||||
|
virtual void open() override;
|
||||||
|
|
||||||
|
virtual void snap() override;
|
||||||
|
|
||||||
|
virtual void stopsnap(bool autosize) override;
|
||||||
|
|
||||||
|
virtual void close() override;
|
||||||
|
|
||||||
|
virtual int read(int addr) override;
|
||||||
|
|
||||||
|
virtual void *readFrameTest(int timeout);
|
||||||
|
|
||||||
|
virtual void UpdateScanParam(HG_ScanConfiguration config) override;
|
||||||
|
|
||||||
|
virtual void createCorrect(int correctmode) override;
|
||||||
|
|
||||||
|
virtual void setFPGATriggerMode(bool autotrigger, int delay) override;
|
||||||
|
|
||||||
|
virtual void setFanMode(int mode) override;
|
||||||
|
|
||||||
|
virtual void fpgaReload() override;
|
||||||
|
|
||||||
|
virtual bool capturerImage() override;
|
||||||
|
|
||||||
|
virtual void waitsnapdone(int state) override;
|
||||||
|
|
||||||
|
virtual bool IsImageQueueEmpty() override;
|
||||||
|
|
||||||
|
virtual void resetimageremain() override;
|
||||||
|
|
||||||
|
virtual std::atomic_int &getimageremain() override;
|
||||||
|
|
||||||
|
virtual void clearimages() override;
|
||||||
|
|
||||||
|
virtual void setScanFlag(bool brun) override;
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "PanelLeds.h"
|
||||||
|
|
||||||
|
|
||||||
|
PanelLeds::PanelLeds()
|
||||||
|
: white("pwr-white"),
|
||||||
|
red("pwr-red"),
|
||||||
|
green("pwr-green")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PanelLeds::~PanelLeds()
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Led.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
|
||||||
|
class PanelLeds
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PanelLeds();
|
||||||
|
~PanelLeds();
|
||||||
|
|
||||||
|
void setStatus(LedStatus status)
|
||||||
|
{
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case LedStatus::Ready:
|
||||||
|
{
|
||||||
|
LOG("LedStatus Ready red off and white off \n");
|
||||||
|
red.off();
|
||||||
|
white.on();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LedStatus::Scanning:
|
||||||
|
{
|
||||||
|
LOG("LedStatus scanning red off and white on 500 \n");
|
||||||
|
red.off();
|
||||||
|
white.on(500);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LedStatus::Abnormal:
|
||||||
|
{
|
||||||
|
LOG("LedStatus Abnormal red on and white off \n");
|
||||||
|
red.on();
|
||||||
|
white.off();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LedStatus::NoPaper:
|
||||||
|
{
|
||||||
|
LOG("LedStatus NoPaper red on 200 and white off \n");
|
||||||
|
red.on(200);
|
||||||
|
white.off();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LedStatus::StopScan:
|
||||||
|
{
|
||||||
|
LOG("LedStatus NoPaper red off and white on 200 \n");
|
||||||
|
red.off();
|
||||||
|
white.on(200);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LedStatus::CoverOpen:
|
||||||
|
{
|
||||||
|
LOG("LedStatus NoPaper red on and white off \n");
|
||||||
|
red.on();
|
||||||
|
white.off();
|
||||||
|
}
|
||||||
|
case LedStatus::Updating:
|
||||||
|
{
|
||||||
|
LOG("LedStatus NoPaper red on and white off \n");
|
||||||
|
red.on(100);
|
||||||
|
white.off();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LedStatus::UpdateDone:
|
||||||
|
{
|
||||||
|
LOG("LedStatus NoPaper red on and white off \n");
|
||||||
|
red.off();
|
||||||
|
white.on(200);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
LOG("LedStatus NoPaper red off and white off \n");
|
||||||
|
red.off();
|
||||||
|
white.off();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Led white;
|
||||||
|
Led red;
|
||||||
|
Led green;
|
||||||
|
};
|
|
@ -0,0 +1,101 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//#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 = 9000;
|
||||||
|
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
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include <algorithm>
|
||||||
|
#include "Properties.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace cppproperties {
|
||||||
|
|
||||||
|
Properties::Properties() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Properties::~Properties() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Properties::GetProperty(const std::string& key) const {
|
||||||
|
if (properties.find(key) == properties.end()) {
|
||||||
|
throw PropertyNotFoundException(key + " does not exist");
|
||||||
|
}
|
||||||
|
return properties.at(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//前面把配置文件参数读取 分成key和val放入map,从map取出val
|
||||||
|
std::string Properties::GetProperty(const std::string& key, const std::string& defaultValue) const {
|
||||||
|
|
||||||
|
if (key.compare("fpga.correctColor.BOffset") == 0)
|
||||||
|
printf("Get Config File Size (path: /usr/local/huago/ “properties” ) = %d \r\n",properties.size());
|
||||||
|
if (properties.find(key) == properties.end()) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return properties.at(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::string> Properties::GetPropertyNames() const {
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
//把配置文件参数写入map
|
||||||
|
void Properties::AddProperty(const std::string& key, const std::string& value) {
|
||||||
|
if (properties.find(key) == properties.end()) {
|
||||||
|
keys.push_back(key);
|
||||||
|
}
|
||||||
|
properties[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Properties::RemoveProperty(const std::string& key) {
|
||||||
|
if (properties.find(key) == properties.end()) {
|
||||||
|
throw PropertyNotFoundException(key + " does not exist");
|
||||||
|
}
|
||||||
|
keys.erase(std::remove(keys.begin(), keys.end(), key), keys.end());
|
||||||
|
properties.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace cppproperties */
|
|
@ -0,0 +1,55 @@
|
||||||
|
#ifndef PROPERTIES_H_
|
||||||
|
#define PROPERTIES_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include "PropertiesException.h"
|
||||||
|
#include "PropertyNotFoundException.h"
|
||||||
|
|
||||||
|
namespace cppproperties {
|
||||||
|
|
||||||
|
class Properties {
|
||||||
|
public:
|
||||||
|
Properties();
|
||||||
|
virtual ~Properties();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the property value from a given key.
|
||||||
|
*
|
||||||
|
* This method throws a PropertyNotFoundException when a given key does not
|
||||||
|
* exist.
|
||||||
|
*/
|
||||||
|
std::string GetProperty(const std::string& key) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the property value from a given key. Use a default value if not found.
|
||||||
|
*/
|
||||||
|
std::string GetProperty(const std::string& key, const std::string& defaultValue) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of property names.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> GetPropertyNames() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new property. If the property already exists, it'll overwrite
|
||||||
|
* the old one.
|
||||||
|
*/
|
||||||
|
void AddProperty(const std::string& key, const std::string& value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the property from a given key.
|
||||||
|
*
|
||||||
|
* If the property doesn't exist a PropertyNotFoundException will be thrown.
|
||||||
|
*/
|
||||||
|
void RemoveProperty(const std::string& key);
|
||||||
|
private:
|
||||||
|
// to preserve the order
|
||||||
|
std::vector<std::string> keys;
|
||||||
|
std::map<std::string, std::string> properties;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace cppproperties */
|
||||||
|
|
||||||
|
#endif /* PROPERTIES_H_ */
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef PROPERTIESEXCEPTION_H_
|
||||||
|
#define PROPERTIESEXCEPTION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
namespace cppproperties {
|
||||||
|
|
||||||
|
class PropertiesException : public std::exception {
|
||||||
|
public:
|
||||||
|
PropertiesException() {}
|
||||||
|
PropertiesException(const std::string& msg) throw() : message(msg) {}
|
||||||
|
|
||||||
|
virtual ~PropertiesException() throw() {}
|
||||||
|
|
||||||
|
const std::string& str() const throw() { return message; }
|
||||||
|
|
||||||
|
virtual const char* what() const throw() { return message.c_str(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string message;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace cppproperties */
|
||||||
|
|
||||||
|
#endif /* PROPERTIESEXCEPTION_H_ */
|
|
@ -0,0 +1,78 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "PropertiesParser.h"
|
||||||
|
#include "PropertiesUtils.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
namespace cppproperties {
|
||||||
|
|
||||||
|
PropertiesParser::PropertiesParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertiesParser::~PropertiesParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//读取配置文件参数放入map // fpga.correctColor.BOffset = 119,119,119,119,119,119
|
||||||
|
//路径 :/usr/local/huago/fpga.properties //key //val
|
||||||
|
Properties PropertiesParser::Read(const std::string& file) {
|
||||||
|
Properties properties;
|
||||||
|
std::ifstream is;
|
||||||
|
is.open(file.c_str());
|
||||||
|
if (is.is_open()) {
|
||||||
|
try {
|
||||||
|
size_t linenr = 0;
|
||||||
|
std::string line;
|
||||||
|
while (getline(is, line)) {
|
||||||
|
if (PropertiesUtils::IsEmptyLine(line) || PropertiesUtils::IsComment(line)) {
|
||||||
|
// ignore it
|
||||||
|
} else if (PropertiesUtils::IsProperty(line)) {
|
||||||
|
std::pair<std::string, std::string> prop = PropertiesUtils::ParseProperty(line);
|
||||||
|
properties.AddProperty(prop.first, prop.second);
|
||||||
|
// if(prop.first == "fpga.correctColor.BOffset")
|
||||||
|
// printf("uuuuuuuuuuuuuuuuuuuu %s\r\n",prop.second.c_str());
|
||||||
|
}
|
||||||
|
++linenr;
|
||||||
|
}
|
||||||
|
is.close();
|
||||||
|
} catch (...) {
|
||||||
|
// don't forget to close the ifstream
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
//写入配置文件
|
||||||
|
void PropertiesParser::Write(const std::string& file, const Properties& props) {
|
||||||
|
std::ofstream os;
|
||||||
|
os.open(file.c_str());
|
||||||
|
if (!os.is_open()) {
|
||||||
|
throw PropertiesException("PropertiesParser::Write(" + file + "): Unable to open file for writing.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const std::vector<std::string>& keys = props.GetPropertyNames();
|
||||||
|
for (std::vector<std::string>::const_iterator i = keys.begin();
|
||||||
|
i != keys.end(); ++i) {
|
||||||
|
os << *i << " = " << props.GetProperty(*i) << std::endl;
|
||||||
|
}
|
||||||
|
os.close();
|
||||||
|
} catch (...) {
|
||||||
|
// don't forget to close the ofstream
|
||||||
|
os.close();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
int fd = open(file.c_str(), O_RDONLY);
|
||||||
|
if (fd > 0)
|
||||||
|
{
|
||||||
|
fchmod(fd,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace cppproperties */
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
#ifndef PROPERTIESPARSER_H_
|
||||||
|
#define PROPERTIESPARSER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <exception>
|
||||||
|
#include "Properties.h"
|
||||||
|
|
||||||
|
namespace cppproperties {
|
||||||
|
|
||||||
|
class PropertiesParser {
|
||||||
|
public:
|
||||||
|
PropertiesParser();
|
||||||
|
virtual ~PropertiesParser();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a properties file and returns a Properties object.
|
||||||
|
*/
|
||||||
|
static Properties Read(const std::string& file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes Properties object to a file.
|
||||||
|
*/
|
||||||
|
static void Write(const std::string& file, const Properties& props);
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace cppproperties */
|
||||||
|
|
||||||
|
#endif /* PROPERTIESPARSER_H_ */
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Fredy Wijaya
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#include "PropertiesUtils.h"
|
||||||
|
|
||||||
|
namespace cppproperties {
|
||||||
|
namespace PropertiesUtils {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const std::string TRIM_DELIMITERS = " \f\n\r\t\v";
|
||||||
|
std::string ltrim(const std::string& str) {
|
||||||
|
std::string::size_type s = str.find_first_not_of(TRIM_DELIMITERS);
|
||||||
|
if (s == std::string::npos) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return str.substr(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RightTrim(const std::string& str) {
|
||||||
|
std::string::size_type s = str.find_last_not_of(TRIM_DELIMITERS);
|
||||||
|
if (s == std::string::npos) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return str.substr(0, s+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LeftTrim(const std::string& str) {
|
||||||
|
std::string rstr = ltrim(str);
|
||||||
|
|
||||||
|
while (rstr != ltrim(rstr)) {
|
||||||
|
rstr = ltrim(rstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Trim(const std::string& str) {
|
||||||
|
return RightTrim(LeftTrim(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsProperty(const std::string& str) {
|
||||||
|
std::string trimmedStr = LeftTrim(str);
|
||||||
|
std::string::size_type s = trimmedStr.find_first_of("=");
|
||||||
|
if (s == std::string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string key = Trim(trimmedStr.substr(0, s));
|
||||||
|
// key can't be empty
|
||||||
|
if (key == "") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::string, std::string> ParseProperty(const std::string& str) {
|
||||||
|
std::string trimmedStr = LeftTrim(str);
|
||||||
|
std::string::size_type s = trimmedStr.find_first_of("=");
|
||||||
|
std::string key = Trim(trimmedStr.substr(0, s));
|
||||||
|
std::string value = LeftTrim(trimmedStr.substr(s+1));
|
||||||
|
|
||||||
|
return std::pair<std::string, std::string>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsComment(const std::string& str) {
|
||||||
|
std::string trimmedStr = LeftTrim(str);
|
||||||
|
return trimmedStr[0] == '#';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEmptyLine(const std::string& str) {
|
||||||
|
std::string trimmedStr = LeftTrim(str);
|
||||||
|
return trimmedStr == "";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PropertiesUtils
|
||||||
|
} // namespace cppproperties
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
#ifndef PROPERTIESUTILS_H_
|
||||||
|
#define PROPERTIESUTILS_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace cppproperties {
|
||||||
|
namespace PropertiesUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Left trims a string.
|
||||||
|
* This function doesn't modify the given str.
|
||||||
|
*/
|
||||||
|
std::string LeftTrim(const std::string& str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Right trims a string.
|
||||||
|
* This function doesn't modify the given str.
|
||||||
|
*/
|
||||||
|
std::string RightTrim(const std::string& str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trims a string (perform a left and right trims).
|
||||||
|
* This function doesn't modify the given str.
|
||||||
|
*/
|
||||||
|
std::string Trim(const std::string& str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is a given string a property. A property must have the following format:
|
||||||
|
* key=value
|
||||||
|
*/
|
||||||
|
bool IsProperty(const std::string& str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a given property into a pair of key and value.
|
||||||
|
*
|
||||||
|
* ParseProperty assumes a given string has a correct format.
|
||||||
|
*/
|
||||||
|
std::pair<std::string, std::string> ParseProperty(const std::string& str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is a given string a comment? A comment starts with #
|
||||||
|
*/
|
||||||
|
bool IsComment(const std::string& str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is a given string empty?
|
||||||
|
*/
|
||||||
|
bool IsEmptyLine(const std::string& str);
|
||||||
|
|
||||||
|
} // namespace PropertiesUtils
|
||||||
|
} // namespace cppproperties
|
||||||
|
|
||||||
|
#endif /* PROPERTIESUTILS_H_ */
|
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
#ifndef PROPERTYNOTFOUNDEXCEPTION_H_
|
||||||
|
#define PROPERTYNOTFOUNDEXCEPTION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
namespace cppproperties {
|
||||||
|
|
||||||
|
class PropertyNotFoundException : public std::exception {
|
||||||
|
public:
|
||||||
|
PropertyNotFoundException() {}
|
||||||
|
PropertyNotFoundException(const std::string& msg) throw() : message(msg) {}
|
||||||
|
|
||||||
|
virtual ~PropertyNotFoundException() throw() {}
|
||||||
|
|
||||||
|
const std::string& str() const throw() { return message; }
|
||||||
|
|
||||||
|
virtual const char* what() const throw() { return message.c_str(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string message;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace cppproperties */
|
||||||
|
|
||||||
|
#endif /* PROPERTYNOTFOUNDEXCEPTION_H_ */
|
|
@ -0,0 +1,38 @@
|
||||||
|
#include "Pwm.h"
|
||||||
|
#include "DevUtil.h"
|
||||||
|
|
||||||
|
#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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Pwm::~Pwm()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#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";
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,329 @@
|
||||||
|
#include "ScanConfig.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
const char * PATH_FPAG_DUNNAN_CONFIG = "/usr/local/huago/dunnan_fpga.properties";
|
||||||
|
const char * PATH_FPAG_HUALING_CONFIG = "/usr/local/huago/hualing_fpga.properties";
|
||||||
|
//#define PATH_FPAG_CONFIG "/usr/local/huago/fpga.properties"
|
||||||
|
#define ETC_FPAG_CONFIG "/etc/fpga.properties"
|
||||||
|
|
||||||
|
Properties ScanConfig::fpgaProperties;
|
||||||
|
CaptureParams ScanConfig::captureParmars;
|
||||||
|
|
||||||
|
static const char *keys[] = {
|
||||||
|
"fpga.correctColor.AExposureR",
|
||||||
|
"fpga.correctColor.AExposureG",
|
||||||
|
"fpga.correctColor.AExposureB",
|
||||||
|
"fpga.correctColor.BExposureR",
|
||||||
|
"fpga.correctColor.BExposureG",
|
||||||
|
"fpga.correctColor.BExposureB",
|
||||||
|
"fpga.correctColor.gainA",
|
||||||
|
"fpga.correctColor.gainB",
|
||||||
|
"fpga.correctColor.AOffset",
|
||||||
|
"fpga.correctColor.BOffset",
|
||||||
|
"fpga.correctGray.AExposureR",
|
||||||
|
"fpga.correctGray.AExposureG",
|
||||||
|
"fpga.correctGray.AExposureB",
|
||||||
|
"fpga.correctGray.BExposureR",
|
||||||
|
"fpga.correctGray.BExposureG",
|
||||||
|
"fpga.correctGray.BExposureB",
|
||||||
|
"fpga.correctGray.gainA",
|
||||||
|
"fpga.correctGray.gainB",
|
||||||
|
"fpga.correctGray.AOffset",
|
||||||
|
"fpga.correctGray.BOffset",
|
||||||
|
"fpga.color.AExposureR",
|
||||||
|
"fpga.color.AExposureG",
|
||||||
|
"fpga.color.AExposureB",
|
||||||
|
"fpga.color.BExposureR",
|
||||||
|
"fpga.color.BExposureG",
|
||||||
|
"fpga.color.BExposureB",
|
||||||
|
"fpga.color.gainA",
|
||||||
|
"fpga.color.gainB",
|
||||||
|
"fpga.color.AOffset",
|
||||||
|
"fpga.color.BOffset",
|
||||||
|
"fpga.gray.AExposureR",
|
||||||
|
"fpga.gray.AExposureG",
|
||||||
|
"fpga.gray.AExposureB",
|
||||||
|
"fpga.gray.BExposureR",
|
||||||
|
"fpga.gray.BExposureG",
|
||||||
|
"fpga.gray.BExposureB",
|
||||||
|
"fpga.gray.gainA",
|
||||||
|
"fpga.gray.gainB",
|
||||||
|
"fpga.gray.AOffset",
|
||||||
|
"fpga.gray.BOffset",
|
||||||
|
"fpga.correctColor.UVExposureA",
|
||||||
|
"fpga.correctGray.UVExposureB",
|
||||||
|
"fpga.color.UVExposureA",
|
||||||
|
"fpga.gray.UVExposureA",
|
||||||
|
};
|
||||||
|
|
||||||
|
int parseInt(const std::string str){
|
||||||
|
if(str.compare(0, 2, "0X") == 0 || str.compare(0, 2, "0x") == 0){
|
||||||
|
return (int)std::strtol(str.c_str(),nullptr,16);
|
||||||
|
}else{
|
||||||
|
return std::atoi(str.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScanConfig::parseIntArray(const std::string& str, std::string split,int* p, int size){
|
||||||
|
int lastPosition = 0;
|
||||||
|
int index = -1;
|
||||||
|
int i = 0;
|
||||||
|
while(-1 != (index=str.find(split , lastPosition)) && i < size)
|
||||||
|
{
|
||||||
|
// vecString.push_back(str.substr(lastPosition, index - lastPosition));
|
||||||
|
*(p + i) = parseInt(str.substr(lastPosition, index - lastPosition));
|
||||||
|
lastPosition = index + split.size();
|
||||||
|
i ++;
|
||||||
|
}
|
||||||
|
std::string lastStr = str.substr(lastPosition);
|
||||||
|
if ( !lastStr.empty() && i < size)
|
||||||
|
{
|
||||||
|
*(p + i) = parseInt(lastStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ScanConfig::ScanConfig():cistype(CIS_T_S0,CIS_T_S1,CIS_T_S2,CIS_T_S3){
|
||||||
|
|
||||||
|
if(cistype.GetCisType () == CISVendor::DUNNAN_CIS_V0)
|
||||||
|
{
|
||||||
|
PATH_FPAG_CONFIG = PATH_FPAG_DUNNAN_CONFIG;
|
||||||
|
if(access(PATH_FPAG_CONFIG,F_OK) == -1){
|
||||||
|
PATH_FPAG_CONFIG = "/usr/local/huago/fpga.properties";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cistype.GetCisType () == CISVendor::HUALIN_CIS_V0)
|
||||||
|
{
|
||||||
|
PATH_FPAG_CONFIG = PATH_FPAG_HUALING_CONFIG;
|
||||||
|
if(access(PATH_FPAG_CONFIG,F_OK) == -1){
|
||||||
|
PATH_FPAG_CONFIG = "/usr/local/huago/fpga.properties";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("PATH_FPAG_CONFIG == %s \r\n",PATH_FPAG_CONFIG);
|
||||||
|
if(access(PATH_FPAG_CONFIG,F_OK) !=-1){
|
||||||
|
fpgaProperties = PropertiesParser::Read(PATH_FPAG_CONFIG);
|
||||||
|
}else{
|
||||||
|
fpgaProperties = PropertiesParser::Read(ETC_FPAG_CONFIG);
|
||||||
|
std::cout<<"error 88888888888888888888"<<std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "fpgaProperties:" << fpgaProperties.GetProperty(std::string("fpga.").append("color").append(".gainB"), "200") << std::endl;
|
||||||
|
parseCaptureParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ScanConfig::~ScanConfig(){
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScanConfig::parseCaptureParams(){
|
||||||
|
std::string str = fpgaProperties.GetProperty("fpga.correctColor.gainA", "50,50,50,50,50,50");
|
||||||
|
printf(" --------1111111111 strstrstr = %s \r\n",str.c_str());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.correctColorGain[0], 6);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.gainB", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.correctColorGain[1], 6);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.AOffset", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.correctColorOffset[0], 6);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.BOffset", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.correctColorOffset[1], 6);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.gainA", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.correctGrayGain[0], 6);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.gainB", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.correctGrayGain[1], 6);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.AOffset", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.correctGrayOffset[0], 6);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.BOffset", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.correctGrayOffset[1], 6);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.gainA", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.colorGain[0], 6);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.gainB", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.colorGain[1], 6);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.AOffset", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.colorOffset[0], 6);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.BOffset", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.colorOffset[1], 6);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.gainA", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.grayGain[0], 6);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.gainB", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.grayGain[1], 6);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.AOffset", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.grayOffset[0], 6);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.BOffset", "50,50,50,50,50,50");
|
||||||
|
parseIntArray(str, std :: string(","), captureParmars.grayOffset[1], 6);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.AExposureR", "200");
|
||||||
|
captureParmars.correctColorExposure[0][0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.AExposureG", "200");
|
||||||
|
captureParmars.correctColorExposure[0][1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.AExposureB", "200");
|
||||||
|
captureParmars.correctColorExposure[0][2] = parseInt(str);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.BExposureR", "200");
|
||||||
|
captureParmars.correctColorExposure[1][0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.BExposureG", "200");
|
||||||
|
captureParmars.correctColorExposure[1][1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.BExposureB", "200");
|
||||||
|
captureParmars.correctColorExposure[1][2] = parseInt(str);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.AExposureR", "200");
|
||||||
|
captureParmars.correctGrayExposure[0][0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.AExposureG", "200");
|
||||||
|
captureParmars.correctGrayExposure[0][1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.AExposureB", "200");
|
||||||
|
captureParmars.correctGrayExposure[0][2] = parseInt(str);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.BExposureR", "200");
|
||||||
|
captureParmars.correctGrayExposure[1][0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.BExposureG", "200");
|
||||||
|
captureParmars.correctGrayExposure[1][1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.BExposureB", "200");
|
||||||
|
captureParmars.correctGrayExposure[1][2] = parseInt(str);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.AExposureR", "200");
|
||||||
|
captureParmars.colorExposure[0][0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.AExposureG", "200");
|
||||||
|
captureParmars.colorExposure[0][1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.AExposureB", "200");
|
||||||
|
captureParmars.colorExposure[0][2] = parseInt(str);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.BExposureR", "200");
|
||||||
|
captureParmars.colorExposure[1][0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.BExposureG", "200");
|
||||||
|
captureParmars.colorExposure[1][1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.BExposureB", "200");
|
||||||
|
captureParmars.colorExposure[1][2] = parseInt(str);
|
||||||
|
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.AExposureR", "200");
|
||||||
|
captureParmars.grayExposure[0][0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.AExposureG", "200");
|
||||||
|
captureParmars.grayExposure[0][1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.AExposureB", "200");
|
||||||
|
captureParmars.grayExposure[0][2] = parseInt(str);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.BExposureR", "200");
|
||||||
|
captureParmars.grayExposure[1][0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.BExposureG", "200");
|
||||||
|
captureParmars.grayExposure[1][1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.BExposureB", "200");
|
||||||
|
captureParmars.grayExposure[1][2] = parseInt(str);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.UVExposureA", "200");
|
||||||
|
captureParmars.uvCorrectColorExposure[0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctColor.UVExposureB", "200");
|
||||||
|
captureParmars.uvCorrectColorExposure[1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.UVExposureA", "200");
|
||||||
|
captureParmars.uvColorExposure[0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.color.UVExposureB", "200");
|
||||||
|
captureParmars.uvColorExposure[1] = parseInt(str);
|
||||||
|
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.UVExposureA", "0");
|
||||||
|
captureParmars.uvCorrectGrayExposure[0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.correctGray.UVExposureB", "0");
|
||||||
|
captureParmars.uvCorrectGrayExposure[1] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.UVExposureA", "0");
|
||||||
|
captureParmars.uvGrayExposure[0] = parseInt(str);
|
||||||
|
str = fpgaProperties.GetProperty("fpga.gray.UVExposureB", "0");
|
||||||
|
captureParmars.uvGrayExposure[1] = parseInt(str);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string parseString(int value){
|
||||||
|
std::string s;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << value;
|
||||||
|
ss >> s;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string parseArrayString(int *array, int len){
|
||||||
|
std::string s;
|
||||||
|
for(int i= 0; i < len; i ++){
|
||||||
|
s.append(parseString(array[i]));
|
||||||
|
if(i < len - 1)s.append(",");
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//δʹ<CEB4><CAB9>
|
||||||
|
void ScanConfig::modifyCaptureParams(const char * key, const char * value){
|
||||||
|
fpgaProperties.AddProperty(key, value);
|
||||||
|
parseCaptureParams();
|
||||||
|
PropertiesParser::Write(PATH_FPAG_CONFIG, fpgaProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ScanConfig::getCaptureParmas(std::string key){
|
||||||
|
std::string ret = fpgaProperties.GetProperty(key, "");
|
||||||
|
if(ret.length() == 0){
|
||||||
|
fpgaProperties = PropertiesParser::Read(PATH_FPAG_CONFIG);
|
||||||
|
ret = fpgaProperties.GetProperty(key, "");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScanConfig::save(){
|
||||||
|
int *p = (int *)&captureParmars;
|
||||||
|
for(int i = 0; i < 4; i ++ ){
|
||||||
|
int *params = p + 30 * i;
|
||||||
|
for(int j = 0; j < 6; j ++ ){
|
||||||
|
fpgaProperties.AddProperty(keys[10 * i + j ], parseString(params[j]));
|
||||||
|
}
|
||||||
|
for(int k = 0; k < 4; k ++ ){
|
||||||
|
fpgaProperties.AddProperty(keys[10 * i + k + 6], parseArrayString(¶ms[6 + 6 * k], 6));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertiesParser::Write(PATH_FPAG_CONFIG, fpgaProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
void ScanConfig::writeParamars(std::string type, int * params){
|
||||||
|
if(type.compare("color") == 0){
|
||||||
|
memcpy(captureParmars.colorExposure, params, 6 * sizeof(int));
|
||||||
|
memcpy(captureParmars.colorGain, ¶ms[6], 12 * sizeof(int));
|
||||||
|
memcpy(captureParmars.colorOffset, ¶ms[18], 12 * sizeof(int));
|
||||||
|
}else if(type.compare("correctColor") == 0){
|
||||||
|
memcpy(captureParmars.correctColorExposure, params, 6 * sizeof(int));
|
||||||
|
memcpy(captureParmars.correctColorGain, ¶ms[6], 12 * sizeof(int));
|
||||||
|
memcpy(captureParmars.correctColorOffset, ¶ms[18], 12 * sizeof(int));
|
||||||
|
}else if(type.compare("gray") == 0){
|
||||||
|
memcpy(captureParmars.grayExposure, params, 6 * sizeof(int));
|
||||||
|
memcpy(captureParmars.grayGain, ¶ms[6], 12 * sizeof(int));
|
||||||
|
memcpy(captureParmars.grayOffset, ¶ms[18], 12 * sizeof(int));
|
||||||
|
}else if(type.compare("correctGray") == 0){
|
||||||
|
memcpy(captureParmars.correctGrayExposure, params, 6 * sizeof(int));
|
||||||
|
memcpy(captureParmars.correctGrayGain, ¶ms[6], 12 * sizeof(int));
|
||||||
|
memcpy(captureParmars.correctGrayOffset, ¶ms[18], 12 * sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".AExposureR", parseString(params[0]));
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".AExposureG", parseString(params[1]));
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".AExposureB", parseString(params[2]));
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".BExposureR", parseString(params[3]));
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".BExposureG", parseString(params[4]));
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".BExposureB", parseString(params[5]));
|
||||||
|
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".gainA", parseArrayString(¶ms[6], 6));
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".gainB", parseArrayString(¶ms[12], 6));
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".AOffset", parseArrayString(¶ms[18], 6));
|
||||||
|
fpgaProperties.AddProperty("fpga." + type + ".BOffset", parseArrayString(¶ms[24], 6));
|
||||||
|
|
||||||
|
PropertiesParser::Write(PATH_FPAG_CONFIG, fpgaProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef SCANCONFIG_H_
|
||||||
|
#define SCANCONFIG_H_
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
#include "PropertiesParser.h"
|
||||||
|
#include "TypeIO.h"
|
||||||
|
|
||||||
|
#define PRO_SCAN_MODE "persist.sys.scan.mode"
|
||||||
|
#define PRO_COLOR_MODE "persist.sys.scan.color"
|
||||||
|
#define PRO_AUTO_ADJUST "persist.sys.scan.adjust"
|
||||||
|
#define PRO_AUTO_CUT "persist.sys.scan.cut"
|
||||||
|
#define PRO_QUALITY "persist.sys.scan.quality"
|
||||||
|
#define PRO_DOUBLE_CHECKED "persist.sys.scan.doublechk"
|
||||||
|
#define PRO_SCAN_QUALITY "persist.sys.scan.quality"
|
||||||
|
#define PRO_SKIP_BLANK "persist.sys.scan.skip"
|
||||||
|
#define PRO_COMPRESS_FORMAT "persist.sys.scan.compress"
|
||||||
|
#define PRO_SCAN_SETTING "persist.sys.scan.setting"
|
||||||
|
#define PRO_SCAN_PAGES "persist.sys.scan.page"
|
||||||
|
#define PRO_SCAN_TOTAL_PAGES "persist.sys.scan.total_page"
|
||||||
|
#define PRO_SCAN_CUOZHI "persist.sys.scan.cuozhi"
|
||||||
|
#define PRO_FPGA_UPDATE "persist.sys.fpga.update"
|
||||||
|
using namespace cppproperties;
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::string toString(const T &v)
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << v;
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ScanConfig{
|
||||||
|
private:
|
||||||
|
static Properties fpgaProperties;
|
||||||
|
void parseCaptureParams();
|
||||||
|
void parseIntArray(const std::string& str, std::string split,int* p, int size);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScanConfig();
|
||||||
|
~ScanConfig();
|
||||||
|
static CaptureParams captureParmars;
|
||||||
|
void modifyCaptureParams(const char *key, const char *value);
|
||||||
|
std::string getCaptureParmas(std::string key);
|
||||||
|
void writeParamars(std::string type, int * params);
|
||||||
|
void save();
|
||||||
|
void cpyCrtParam();
|
||||||
|
TypeIO cistype;
|
||||||
|
const char * PATH_FPAG_CONFIG ;
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -0,0 +1,479 @@
|
||||||
|
#include "Scanner.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "filetools.h"
|
||||||
|
#include "fpgacontrol.h"
|
||||||
|
#include "MemoryInfo.h"
|
||||||
|
#include "SysInforTool.h"
|
||||||
|
#include "USBProtocol.h"
|
||||||
|
|
||||||
|
#define BTNSTART 0
|
||||||
|
#define BTNSTOP 1
|
||||||
|
#define BTNPOWER 2
|
||||||
|
|
||||||
|
Scanner::Scanner(ScannerGlue glue)
|
||||||
|
: motorZouzhi(),
|
||||||
|
motorCuozhi(),
|
||||||
|
m_glue(glue),
|
||||||
|
m_isPulling(false),
|
||||||
|
m_isDoublePaper(false),
|
||||||
|
isPaperInit(false),
|
||||||
|
m_jamPaper(false),
|
||||||
|
m_jamIn(false),
|
||||||
|
m_correctting(false),
|
||||||
|
waitpapertime(200),
|
||||||
|
m_scansysinfo(nullptr)
|
||||||
|
{
|
||||||
|
cisvendor = GetCisType();
|
||||||
|
LOG("Scanner init --------- \n");
|
||||||
|
m_scaninfo = GetScanInfoFromJson();
|
||||||
|
m_fpga = std::make_shared<FpgaComm>();
|
||||||
|
int version = m_fpga->read(15);
|
||||||
|
LOG("FPGA Version = %d \n",m_fpga->read(15));
|
||||||
|
|
||||||
|
capturer.reset(new MultiFrameCapture(m_glue, m_fpga,cisvendor));
|
||||||
|
|
||||||
|
// capturer.reset(new Capturer(m_glue,m_fpga));
|
||||||
|
capturer->SetParent(this);
|
||||||
|
fpgacontrol fc(version);
|
||||||
|
if (fc.ifneedupdatefpga())
|
||||||
|
{
|
||||||
|
if (fc.updatefpga())
|
||||||
|
{
|
||||||
|
//system("sh /etc/reloadfpga.sh");
|
||||||
|
system("poweroff");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG("error error update fpga error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto btnevent = [this](const int eventtype)
|
||||||
|
{
|
||||||
|
if (!IsScanning()) //未扫描
|
||||||
|
{
|
||||||
|
LOG("enter low power mode 000000000000 \n");
|
||||||
|
if (eventtype == BTNPOWER)
|
||||||
|
{
|
||||||
|
LOG("enter low power mode \n");
|
||||||
|
system("echo mem > /sys/power/state");
|
||||||
|
}
|
||||||
|
else if (eventtype == BTNSTART)
|
||||||
|
{
|
||||||
|
// put(S_EVT_START_SCAN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //扫描中
|
||||||
|
{
|
||||||
|
if (eventtype == BTNSTOP)
|
||||||
|
{
|
||||||
|
put(S_EVT_STOP_SCAN);
|
||||||
|
LOG("BTN_STOP put(S_EVT_STOP_SCAN)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sensor = std::make_shared<Sensor>(sysEvent);
|
||||||
|
m_keyboard.reset(new huagao::Keyboard(btnevent));
|
||||||
|
m_keyboard->init();
|
||||||
|
motorZouzhi.enablePower(true);
|
||||||
|
motorZouzhi.setSpeed(4000);
|
||||||
|
motorCuozhi.setSpeed(3000);
|
||||||
|
motorCuozhi.setDirection(false);
|
||||||
|
//sensor->isPaperAtScan();
|
||||||
|
//system("cat /sys/class/gpio/gpio226/value");
|
||||||
|
sensor->enableDoubleSensor(true);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
sensor->enableDoubleSensor(false);
|
||||||
|
FsmState::setScanner(this);
|
||||||
|
threadRunMessageLoop = std::thread(&Scanner::runMessageLoop, this);
|
||||||
|
Motor::enablePower(true);
|
||||||
|
//meminfo = MemoryInfo::GetInstance();
|
||||||
|
//GetSysInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
Scanner::~Scanner()
|
||||||
|
{
|
||||||
|
Motor::enablePower(false);
|
||||||
|
sysEvent.Clear();
|
||||||
|
sysEvent.ShutDown();
|
||||||
|
bMsgLoop = false;
|
||||||
|
threadRunMessageLoop.join();
|
||||||
|
|
||||||
|
m_DstScannum = 0;
|
||||||
|
if (threadRunScan.joinable())
|
||||||
|
threadRunScan.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Scanner::updateSpeedMode(int speed)
|
||||||
|
{
|
||||||
|
m_scaninfo = GetScanInfoFromJson();
|
||||||
|
if(m_scaninfo.SpeedMode==0)
|
||||||
|
m_scaninfo.SpeedMode=3;
|
||||||
|
LOG("Scanner SET updateSpeedMode %d------ \n",m_scaninfo.SpeedMode);
|
||||||
|
unsigned int t_dpi=m_config.params.dpi;
|
||||||
|
// if(typeid(*capturer)==typeid(MonoCapturer))
|
||||||
|
// {
|
||||||
|
// if(m_config.params.dpi==0x03&& m_scansysinfo->IsSmallRam())
|
||||||
|
// t_dpi=0x02;
|
||||||
|
// else
|
||||||
|
// t_dpi = m_config.params.dpi;
|
||||||
|
// }
|
||||||
|
if(typeid(*capturer)==typeid(MultiFrameCapture))
|
||||||
|
if(m_config.params.pageSize == 17 || m_config.params.pageSize == 19) //长文稿采用600dpi模式扫描
|
||||||
|
t_dpi = 3;
|
||||||
|
motorCuozhi.speedChange(m_scaninfo.SpeedMode, t_dpi,m_config.params.isColor);
|
||||||
|
motorZouzhi.speedChange(m_scaninfo.SpeedMode, t_dpi,m_config.params.isColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scanner::startScan()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (threadRunScan.joinable())
|
||||||
|
threadRunScan.join();
|
||||||
|
stop_countdown();
|
||||||
|
updateSpeedMode(4);
|
||||||
|
// //开始进行扫描
|
||||||
|
threadRunScan = std::thread(&Scanner::runScan, this);
|
||||||
|
writesyslog(LOG_INFO, getmeminfo());
|
||||||
|
|
||||||
|
|
||||||
|
// HG_ScanConfiguration cfg;
|
||||||
|
// cfg.params.dpi=2;
|
||||||
|
// cfg.params.isColor = 1;
|
||||||
|
// cfg.params.pageSize = 1;
|
||||||
|
// capturer->UpdateScanParam(cfg);
|
||||||
|
|
||||||
|
// for(int i = 0;i<1;i++)
|
||||||
|
// {
|
||||||
|
// capturer->open();
|
||||||
|
// capturer->snap();
|
||||||
|
// capturer->capturerImage();
|
||||||
|
// capturer->close();
|
||||||
|
// // std::this_thread::sleep_for(std::chrono::milliseconds(4000));//避免scanpin io 开始异常
|
||||||
|
// }
|
||||||
|
// //capturer->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scanner::runMessageLoop()
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(3000));//避免scanpin io 开始异常
|
||||||
|
GetSysInfo();//待fpga 重启完成
|
||||||
|
FsmState *fsmState = FsmStateManagerEx<InitState>::GetState();
|
||||||
|
while (bMsgLoop)
|
||||||
|
{
|
||||||
|
ScanEvent evt = sysEvent.Take();
|
||||||
|
//LOG("\n---------------------%d--------------------------\n", evt);
|
||||||
|
fsmState = fsmState->on_event(evt);
|
||||||
|
//printf("current fsmState =%s ",typeid(*fsmState).name());
|
||||||
|
processevent(fsmState, evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scanner::processevent(FsmState *fsmState, ScanEvent event)
|
||||||
|
{
|
||||||
|
LOG("processevent Event:%d\n", (int)event);
|
||||||
|
if (fsmState == nullptr)
|
||||||
|
{
|
||||||
|
LOG("processevent BBBBBBBBBBBBBB Event:%d\n", (int)event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeid(*fsmState) == typeid(CoverOpenState))
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent(1, "Cover Open");
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_SCAN_STOPPED)
|
||||||
|
{
|
||||||
|
if (!m_correctting)
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent(70, "Scan done");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_JAM_IN)
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent(4, "Feed error");
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_DOUBLEPAPER)
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent(16, "Double feed");
|
||||||
|
}
|
||||||
|
else if (event == S_EVT_JAM_OUT || typeid(*fsmState) == typeid(ErrorJamState))
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent(8, "Jam out");
|
||||||
|
}
|
||||||
|
else if (typeid(*fsmState) == typeid(ErrorState) && m_jamIn == true)
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent(4, "Feed error");
|
||||||
|
}
|
||||||
|
if (!IsScanning() && (typeid(*fsmState) == typeid(ErrorJamState) ||
|
||||||
|
typeid(*fsmState) == typeid(CoverOpenState) ||
|
||||||
|
(typeid(*fsmState) == typeid(ErrorState) && m_jamIn == true)))
|
||||||
|
{
|
||||||
|
if (!m_correctting)
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent(70, "Scan Stop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int imageindex = 0;
|
||||||
|
void Scanner::runScan()
|
||||||
|
{
|
||||||
|
LOG("-------------Scanner RunScan Start-------------\r\n");
|
||||||
|
capturer->open();
|
||||||
|
motorZouzhi.start();
|
||||||
|
motorCuozhi.pauseWaitForThread();
|
||||||
|
//capturer->open();
|
||||||
|
sensor->enableDoubleSensor(false);
|
||||||
|
if (!isPaperInit)
|
||||||
|
{
|
||||||
|
preFeed();
|
||||||
|
isPaperInit = true;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
std::cout << string_format("reg[%d] = 0x%08x", i, capturer->read(i)) << std::endl;
|
||||||
|
}
|
||||||
|
imageindex = 0;
|
||||||
|
capturer->setFPGATriggerMode(false, 0);
|
||||||
|
capturer->setFanMode(3);
|
||||||
|
sensor->resetPaperPin();
|
||||||
|
capturer->clearimages();
|
||||||
|
capturer->resetimageremain();
|
||||||
|
capturer->setScanFlag(true);
|
||||||
|
int tmp_recordScannum = 0;
|
||||||
|
bool b_autosize = m_config.params.pageSize==(int)PaperSize::G400_AUTO ||
|
||||||
|
m_config.params.pageSize==(int)PaperSize::G400_MAXAUTO ||
|
||||||
|
m_config.params.pageSize==(int)PaperSize::G400_MAXSIZE;
|
||||||
|
StopWatch sw;
|
||||||
|
while (m_DstScannum > 0)
|
||||||
|
{
|
||||||
|
m_isDoublePaper = false;
|
||||||
|
m_jamPaper = false;
|
||||||
|
m_jamIn = false;
|
||||||
|
if (!sensor->isPaperStandby()) //无纸
|
||||||
|
{
|
||||||
|
if (!sensor->waitPaperStandBy(0))
|
||||||
|
{
|
||||||
|
// isPaperInit = false;
|
||||||
|
// this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
LOG("\n ----------------EXIT 0000000000 cnt=%d---------------- \n",m_DstScannum);
|
||||||
|
put(S_EVT_STOP_SCAN);
|
||||||
|
LOG("STOP STOP STOP RUNSCAN \n");
|
||||||
|
writesyslog(LOG_INFO, getmeminfo());
|
||||||
|
writesyslog(LOG_INFO, "no paper scanner stop scan\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//LOG(" Detect Feeder loaded ,Paper Ready !!! \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor->enableDoubleSensor(m_config.params.doubleFeeded);
|
||||||
|
//LOG("enableDoubleSensor QQQQQQQ:%s %s\n", m_config.params.doubleFeeded ? "true" : "false",GetCurrentTimeStamp(2).c_str());
|
||||||
|
if (m_DstScannum == 0) //被取消扫描了
|
||||||
|
{
|
||||||
|
LOG("canceled canceled canceled 999999999999999999999999999999999999999999 \n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
motorCuozhi.startAsyn();
|
||||||
|
if (!sensor->isPaperStandby())
|
||||||
|
{
|
||||||
|
put(S_EVT_STOP_SCAN);
|
||||||
|
LOG("START SCAN LOOP STOP STOP STOP\n");
|
||||||
|
writesyslog(LOG_INFO, getmeminfo());
|
||||||
|
writesyslog(LOG_INFO, "no paper scanner stop scan\n");
|
||||||
|
isRested = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
isRested = false;
|
||||||
|
if (!sensor->waitPaperIn(3000))
|
||||||
|
{
|
||||||
|
LOG("START SCAN LOOP S_EVT_JAM_IN S_EVT_JAM_IN S_EVT_JAM_IN\n");
|
||||||
|
if (!m_isDoublePaper)
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent(4, "Feed error");
|
||||||
|
m_jamIn = true;
|
||||||
|
put(S_EVT_JAM_IN);
|
||||||
|
m_scaninfo.JamInNum++;
|
||||||
|
//writesyslog(LOG_INFO, "paper jam in error \n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//capturer->snap();
|
||||||
|
motorCuozhi.pauseWaitForThread();
|
||||||
|
int i = 0;
|
||||||
|
int max = 7;
|
||||||
|
#ifdef G400
|
||||||
|
if(m_config.params.pageSize >= (int)PaperSize::G400_LONGLETTER)
|
||||||
|
max = m_scaninfo.SpeedMode>3?10:16;
|
||||||
|
else
|
||||||
|
max = m_scaninfo.SpeedMode>3?5:8;
|
||||||
|
#else
|
||||||
|
if(m_config.params.pageSize >= (int)PaperSize::G400_LONGLETTER)
|
||||||
|
max = m_scaninfo.SpeedMode>3?10:25;
|
||||||
|
else
|
||||||
|
max = m_scaninfo.SpeedMode>3?5:8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
max = m_config.params.dpi > 2 ? 30 : max * m_config.params.dpi;
|
||||||
|
if(m_config.params.pageSize == 17 || m_config.params.pageSize == 19)
|
||||||
|
max = 200;
|
||||||
|
LOG("paper pauseWaitForThread \n");
|
||||||
|
waitpapertime = 400;
|
||||||
|
while (!sensor->waitPaperOut(waitpapertime) && i < max)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
if (!sensor->isPaperIn())
|
||||||
|
{
|
||||||
|
LOG("paper 假卡纸了。。。。。\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG("paper isPaperIn \n");
|
||||||
|
if (i == max && sensor->isPaperIn())
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!m_isDoublePaper)
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent(8, "Jam out"); //卡纸
|
||||||
|
m_jamPaper = true;
|
||||||
|
put(S_EVT_JAM_OUT);
|
||||||
|
m_scaninfo.JamOutNum++;
|
||||||
|
LOG("paper 卡纸了。。。。。\n");
|
||||||
|
writesyslog(LOG_INFO, "paper jam out error\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// m_glue.m_deviceevent(16); //双张
|
||||||
|
// LOG("paper 双张了。。。。。\n");
|
||||||
|
m_scaninfo.DoubleNum++;
|
||||||
|
writesyslog(LOG_INFO, "paper double paper error\n");
|
||||||
|
}
|
||||||
|
//capturer->stopsnap(b_autosize);
|
||||||
|
//capturer->waitsnapdone(1);//等待采集完成
|
||||||
|
//this_thread::sleep_for(std::chrono::milliseconds(500));//200 80ms 600 260ms
|
||||||
|
LOG("\n ----------------EXIT 11111---------------- \n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
LOG("\nclose double sensor %s\n",GetCurrentTimeStamp(2).c_str());
|
||||||
|
sensor->enableDoubleSensor(false);
|
||||||
|
|
||||||
|
if(b_autosize)
|
||||||
|
{
|
||||||
|
int dly_speed= (5 - m_scaninfo.SpeedMode)*10;
|
||||||
|
int delay = m_config.params.dpi==0x02?70:(m_config.params.dpi==0x03?350: 20);
|
||||||
|
if((m_config.params.pageSize == 17 || m_config.params.pageSize == 19)&&(delay < 350))
|
||||||
|
delay = 350;
|
||||||
|
if(m_config.params.pageSize == 18)
|
||||||
|
delay = std::max(delay,80);
|
||||||
|
delay+=dly_speed;
|
||||||
|
LOG("AutoSize sleep_for delay=%d \n",delay);
|
||||||
|
this_thread::sleep_for(std::chrono::milliseconds(delay));//200 80ms 600 260ms
|
||||||
|
}
|
||||||
|
if(b_autosize)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds((5 - m_scaninfo.SpeedMode)*10*m_config.params.dpi));
|
||||||
|
if(sensor->isPaperAtScan())
|
||||||
|
{
|
||||||
|
m_glue.m_deviceevent((int)HG_ScannerStatus::PAPER_HOLE,"paper have hole");
|
||||||
|
capturer->stopsnap(b_autosize);
|
||||||
|
capturer->waitsnapdone(1);//等待采集完成
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
}
|
||||||
|
LOG("\nclose b_autosize %s\n",GetCurrentTimeStamp(2).c_str());
|
||||||
|
capturer->stopsnap(b_autosize);
|
||||||
|
capturer->waitsnapdone(m_isDoublePaper || m_jamPaper);//等待采集完成
|
||||||
|
m_DstScannum--;
|
||||||
|
m_scaninfo.RollerNum++;
|
||||||
|
m_scaninfo.TotalScanned++;
|
||||||
|
tmp_recordScannum++;
|
||||||
|
writesyslog(LOG_INFO, getmeminfo());
|
||||||
|
|
||||||
|
if (m_DstScannum == 0)
|
||||||
|
{
|
||||||
|
LOG("\n ----------------EXIT 2222 cnt=%d---------------- \n",m_DstScannum);
|
||||||
|
this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
|
||||||
|
put(S_EVT_STOP_SCAN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sw.reset();
|
||||||
|
while (meminfo->GetMemoryUsed() > 70.0f||(m_config.params.dpi ==0x03 && capturer->getimageremain()>1)) //内存占用高于75%
|
||||||
|
{
|
||||||
|
if (sw.elapsed_s() < 20.0)
|
||||||
|
std::this_thread::yield();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG("\n ----------------EXIT 3333---------------- \n");
|
||||||
|
put(S_EVT_STOP_SCAN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// motorCuozhi.stop();
|
||||||
|
// motorZouzhi.stop();
|
||||||
|
// auto js = GetScanInfoFromJson();
|
||||||
|
// m_scaninfo.SleepTime = js.SleepTime;
|
||||||
|
m_DstScannum = 0;
|
||||||
|
sensor->enableDoubleSensor(false);
|
||||||
|
sensor->resetPaperPin();
|
||||||
|
capturer->setScanFlag(false);
|
||||||
|
capturer->close();
|
||||||
|
int t_delay = m_config.params.dpi == 0x02 ? 150 : (m_config.params.dpi == 0x03 ? 350 : 100);
|
||||||
|
this_thread::sleep_for(std::chrono::milliseconds(t_delay)); //走纸多转一会儿 确保扫描传感器过了之后 纸能出完
|
||||||
|
capturer->setFanMode(0);
|
||||||
|
LOG("\n--------------------------scan done --------------------------------\n");
|
||||||
|
std::string loginfo = "current scan session scanned " + to_string(tmp_recordScannum) + " page paper\n";
|
||||||
|
writesyslog(LOG_INFO, loginfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scanner::CreatCorrectData(int correctmode)
|
||||||
|
{
|
||||||
|
m_correctting = true;
|
||||||
|
LOG("\n-----------------校正模式 %d-----------------------\n",correctmode);
|
||||||
|
capturer->createCorrect(correctmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scanner::preFeed()
|
||||||
|
{
|
||||||
|
int sleeptime = 300;
|
||||||
|
motorCuozhi.feeding();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(sleeptime));
|
||||||
|
motorCuozhi.pause();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Scanner::GetSysInfo()
|
||||||
|
{
|
||||||
|
meminfo = MemoryInfo::GetInstance();
|
||||||
|
LOG(" GetSysInfo-------- \n");
|
||||||
|
auto scannerinfo = GetScanInfo();
|
||||||
|
auto fwverion = mapFradme_SP[scannerinfo.SpeedMode].FWVERSIO;
|
||||||
|
ScannerSysInfo info = {
|
||||||
|
.CPU = SCPU::CPU_3288,
|
||||||
|
.Systype = SysType::Sys_Linux_Debian,
|
||||||
|
.Screentype = ScreenType::ST_None,
|
||||||
|
.MtBoardVersion = 0x20220114,
|
||||||
|
.MtType = GetSMBType(),
|
||||||
|
.FPGAVersion = m_fpga->read(15),
|
||||||
|
.Cistype = (HGCISType)GetCisType(),
|
||||||
|
.ResSup = {200, 300, 0},
|
||||||
|
.MemTotal = 0,
|
||||||
|
.DiskTotal = 100,
|
||||||
|
.DiskUsed = 0,
|
||||||
|
.KernelVersion = "",
|
||||||
|
.Have_EthernPort = 0,
|
||||||
|
.ServiceVersion = fwverion,
|
||||||
|
.UsbProtocol = 1.0};
|
||||||
|
LOG("FPGAVersion=%08x \n",info.FPGAVersion);
|
||||||
|
m_scansysinfo.reset(new SysInforTool(info));
|
||||||
|
return m_scansysinfo->GetSysInfo();
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
#include "CuoZhiMotor.h"
|
||||||
|
#include "ZouZhiMotor.h"
|
||||||
|
#include "Sensor.h"
|
||||||
|
#include "PanelLeds.h"
|
||||||
|
#include "BlockingQueue.h"
|
||||||
|
#include "FsmState.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "MultiFrameCapture.h"
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
#include "Keyboard.h"
|
||||||
|
#include "utilsfunc.h"
|
||||||
|
#include "filetools.h"
|
||||||
|
#include "SysInforTool.h"
|
||||||
|
#include "MotorConfig.h"
|
||||||
|
#include "correct_ultis.h"
|
||||||
|
#include "FpgaComm.h"
|
||||||
|
class ICapturer;
|
||||||
|
class MemoryInfo;
|
||||||
|
// class SysInforTool;
|
||||||
|
|
||||||
|
class Scanner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Scanner(ScannerGlue glue);
|
||||||
|
~Scanner();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool isRested = false;
|
||||||
|
void startScan();
|
||||||
|
void emergency_stop(int id)
|
||||||
|
{
|
||||||
|
sensor->enableDoubleSensor(false);
|
||||||
|
sensor->cancelWaitPaper();
|
||||||
|
m_DstScannum = 0;
|
||||||
|
if (id == 1) //双张
|
||||||
|
m_glue.m_deviceevent(16, "double feed");
|
||||||
|
|
||||||
|
motorCuozhi.stop();
|
||||||
|
motorZouzhi.stop();
|
||||||
|
//capturer->close();
|
||||||
|
put(S_EVT_SCAN_STOPPED);
|
||||||
|
SaveScaninfo(m_scaninfo);
|
||||||
|
start_enter_lowpwoer();
|
||||||
|
LOG("emergency_stop capturer->close() \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_scan()
|
||||||
|
{
|
||||||
|
//LOG("!!!!!!!!!!!!!!!!!!!!!stop_scan() waitting snap session done \n");
|
||||||
|
sensor->enableDoubleSensor(false);
|
||||||
|
sensor->cancelWaitPaper();
|
||||||
|
m_DstScannum = 0;
|
||||||
|
//LOG("!!!!!!!!!!!!!!!!!!!!!!!!!!stop_scan() waitting snap session done \n");
|
||||||
|
if (threadRunScan.joinable())
|
||||||
|
threadRunScan.join();
|
||||||
|
motorZouzhi.stop();
|
||||||
|
motorCuozhi.stop();
|
||||||
|
// std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
//capturer->close();
|
||||||
|
put(S_EVT_SCAN_STOPPED);
|
||||||
|
SaveScaninfo(m_scaninfo);
|
||||||
|
start_enter_lowpwoer();
|
||||||
|
//LOG("stop_scan() readimageDone() exit22222222 \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Sensor &getSensor() { return *sensor.get(); }
|
||||||
|
PanelLeds &getPanelLeds() { return panelLeds; }
|
||||||
|
int readreg(int addr) { return capturer->read(addr); }
|
||||||
|
void put(ScanEvent evt) { sysEvent.Put(evt); }
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
if (!sensor->isPaperStandby())
|
||||||
|
{
|
||||||
|
motorCuozhi.reset();
|
||||||
|
isRested = true;
|
||||||
|
isPaperInit = false;
|
||||||
|
LOG("Scanner->motorCuozhi is reseted \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void paperReady()
|
||||||
|
{
|
||||||
|
LOG("paperReady 22222222 \n");
|
||||||
|
motorZouzhi.start();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
motorZouzhi.stop();
|
||||||
|
}
|
||||||
|
bool isFeederLoaded() { return sensor->isPaperStandby(); }
|
||||||
|
void ConfigScanParam(HG_ScanConfiguration config)
|
||||||
|
{
|
||||||
|
// if (config.params.dpi == 0)
|
||||||
|
// config.params.dpi = 1;
|
||||||
|
|
||||||
|
m_config = config;
|
||||||
|
LOG("m_config.params.dpi = %d \n \
|
||||||
|
m_config.params.isColor = %d \n \
|
||||||
|
m_config.params.pageSize = %d \n \
|
||||||
|
m_config.params.isCorrect = %d \n",
|
||||||
|
m_config.params.dpi,
|
||||||
|
m_config.params.isColor,
|
||||||
|
m_config.params.pageSize,
|
||||||
|
m_config.params.isCorrect);
|
||||||
|
capturer->UpdateScanParam(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatCorrectData(int correctmode);
|
||||||
|
void SetDstScanNum(int scannum) { m_DstScannum = scannum; }
|
||||||
|
void paper_pullout()
|
||||||
|
{
|
||||||
|
LOG("paper_pullout 22222222 \n");
|
||||||
|
if (!m_isPulling)
|
||||||
|
m_isPulling = true;
|
||||||
|
|
||||||
|
motorCuozhi.stop();
|
||||||
|
motorZouzhi.speedChange(1);
|
||||||
|
motorZouzhi.setDirection(1);
|
||||||
|
motorZouzhi.start();
|
||||||
|
if (sensor->waitPaperOut(5000))
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
||||||
|
motorZouzhi.stop();
|
||||||
|
motorZouzhi.speedRecover();
|
||||||
|
m_isPulling = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetIsDoublePaper(bool isdoublepaper)
|
||||||
|
{
|
||||||
|
m_isDoublePaper = isdoublepaper;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetIsDoublePaper()
|
||||||
|
{
|
||||||
|
return m_isDoublePaper;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetIsJamPaper()
|
||||||
|
{
|
||||||
|
return m_jamPaper;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetIsJamIn()
|
||||||
|
{
|
||||||
|
return m_jamIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetJamIn()
|
||||||
|
{
|
||||||
|
m_jamIn = false;
|
||||||
|
}
|
||||||
|
bool IsScanning()
|
||||||
|
{
|
||||||
|
return !capturer->IsImageQueueEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeParamars(std::string type, int *value)
|
||||||
|
{
|
||||||
|
// capturer->m_configprop->writeParamars(type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateScanInfo()
|
||||||
|
{
|
||||||
|
m_scaninfo = GetScanInfoFromJson();
|
||||||
|
MotorConfig::MTBDType smbtype = GetSMBType() == SMBType::MB_DRV_8825 ? MotorConfig::MTBDType::MT_DRV : MotorConfig::MTBDType::MT_TMC;
|
||||||
|
auto params = MotorConfig().GetMotorSpeedParams(true, smbtype);
|
||||||
|
for (int i = 0; i < params.size(); i++)
|
||||||
|
{
|
||||||
|
if (params[i].speed == m_scaninfo.SpeedMode)
|
||||||
|
{
|
||||||
|
// auto fpgaparam = GetFpgaparam(params[i].dpi, params[i].colormode);
|
||||||
|
// fpgaparam.Sp = params[i].sp;
|
||||||
|
// SaveFpgaparam(fpgaparam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf(" UpdateScanInfo speed mode = %d \n",m_scaninfo.SpeedMode);
|
||||||
|
updateSpeedMode(m_scaninfo.SpeedMode);
|
||||||
|
}
|
||||||
|
CaptureParams GetCaptureParams()
|
||||||
|
{
|
||||||
|
CaptureParams param;
|
||||||
|
return param;
|
||||||
|
// return capturer->m_configprop->captureParmars;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScannerScanInfo &GetScanInfo()
|
||||||
|
{
|
||||||
|
return m_scaninfo;
|
||||||
|
}
|
||||||
|
void updateSpeedMode(int speed);
|
||||||
|
void ResetCorrectflags() { m_correctting = false; }
|
||||||
|
void StopScan(int Evt)
|
||||||
|
{
|
||||||
|
put(S_EVT_STOP_SCAN);
|
||||||
|
//capturer->clearimages();
|
||||||
|
//capturer->resetimageremain();
|
||||||
|
//m_glue.m_deviceevent(70, "Scan done");
|
||||||
|
}
|
||||||
|
std::string GetSysInfo();
|
||||||
|
|
||||||
|
ScannerSysInfo &GetSysinfoStruct() { return m_scansysinfo->GetInfo(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
//处理事件
|
||||||
|
void processevent(FsmState *fsmState, ScanEvent event);
|
||||||
|
void startZouzhi() { motorZouzhi.start(); }
|
||||||
|
void stopZouzhi() { motorZouzhi.stop(); }
|
||||||
|
void startCuozhi() { motorCuozhi.start(); }
|
||||||
|
void stopCuozhi() { motorCuozhi.stop(); }
|
||||||
|
//运行消息循环
|
||||||
|
void runMessageLoop();
|
||||||
|
void runScan();
|
||||||
|
void preFeed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ZouZhiMotor motorZouzhi;
|
||||||
|
CuoZhiMotor motorCuozhi;
|
||||||
|
std::shared_ptr<Sensor> sensor;
|
||||||
|
PanelLeds panelLeds;
|
||||||
|
std::thread threadRunScan;
|
||||||
|
std::thread threadRunMessageLoop;
|
||||||
|
volatile bool bMsgLoop = true;
|
||||||
|
BlockingQueue<ScanEvent> sysEvent;
|
||||||
|
std::shared_ptr<ICapturer> capturer;
|
||||||
|
std::shared_ptr<huagao::Keyboard> m_keyboard;
|
||||||
|
ScannerGlue m_glue;
|
||||||
|
HG_ScanConfiguration m_config;
|
||||||
|
ScannerScanInfo m_scaninfo;
|
||||||
|
std::thread m_correctThread;
|
||||||
|
volatile int m_DstScannum = 500;
|
||||||
|
bool m_isPulling;
|
||||||
|
volatile bool m_isDoublePaper;
|
||||||
|
volatile bool m_jamPaper;
|
||||||
|
volatile bool m_jamIn;
|
||||||
|
bool isPaperInit;
|
||||||
|
volatile bool m_correctting;
|
||||||
|
int waitpapertime;
|
||||||
|
MemoryInfo *meminfo;
|
||||||
|
CISVendor cisvendor;
|
||||||
|
std::shared_ptr<SysInforTool> m_scansysinfo;
|
||||||
|
std::shared_ptr<ICapturer> m_capturer;
|
||||||
|
std::shared_ptr<FpgaComm> m_fpga;
|
||||||
|
};
|
|
@ -0,0 +1,256 @@
|
||||||
|
#include "Sensor.h"
|
||||||
|
#include "DevUtil.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "filetools.h"
|
||||||
|
|
||||||
|
//FileTools ftt("/home/linaro/scanpin.log");
|
||||||
|
|
||||||
|
Sensor::Sensor(BlockingQueue<ScanEvent> &sysEvents)
|
||||||
|
:events(sysEvents),
|
||||||
|
pwm2(2),
|
||||||
|
coverPin(PIN_PORT_7010::OPEN_COVER_SENSOR),
|
||||||
|
paperPin(PIN_PORT_7010::HAVE_OR_NO_PAPER),
|
||||||
|
scanPin (PIN_PORT_7010::SCAN_SENSOR),
|
||||||
|
doubleEnablePin(PIN_PORT_7010::ULTRASONIC_SENSORS_ON),
|
||||||
|
double_out0_Pin(PIN_PORT_7010::ULTRASONIC_SENSORS_OUT0),
|
||||||
|
double_out1_Pin(PIN_PORT_7010::ULTRASONIC_SENSORS_OUT1),
|
||||||
|
sensor_power(PIN_PORT_7010::SENSOR_POWER)
|
||||||
|
|
||||||
|
{
|
||||||
|
pwm2.enable(Gpio::High);
|
||||||
|
pwm2.setFreq(2583);
|
||||||
|
sensor_power.setDirection(Gpio::in);
|
||||||
|
sensor_power.setValue(Gpio::High); //默认打开电源
|
||||||
|
|
||||||
|
coverPin.setDirection(Gpio::in);
|
||||||
|
paperPin.setDirection(Gpio::in);
|
||||||
|
double_out0_Pin.setDirection(Gpio::in);
|
||||||
|
double_out1_Pin.setDirection(Gpio::in);
|
||||||
|
//paperJamPin.setDirection(Gpio::in);
|
||||||
|
scanPin.setDirection(Gpio::in);
|
||||||
|
scanPin.setEdge(Gpio::both);
|
||||||
|
doubleEnablePin.setDirection(Gpio::out);
|
||||||
|
coverPin.setEdge(Gpio::both);
|
||||||
|
paperPin.setEdge(Gpio::both);
|
||||||
|
double_out0_Pin.setEdge(Gpio::both);
|
||||||
|
double_out1_Pin.setEdge(Gpio::both);
|
||||||
|
|
||||||
|
//std::cout<<"scanPin "<< scanPin.getValue()<<std::endl;
|
||||||
|
thread_monitor = std::thread(&Sensor::monitor, this);
|
||||||
|
thread_monitor2 = std::thread(&Sensor::monitor2, this);
|
||||||
|
enableDoubleSensor(true);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
enableDoubleSensor(false);
|
||||||
|
LOG(" init sensor done \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Sensor::~Sensor()
|
||||||
|
{
|
||||||
|
bMonitor = false;
|
||||||
|
bMonitor2 = false;
|
||||||
|
if(thread_monitor.joinable())
|
||||||
|
thread_monitor.join();
|
||||||
|
if(thread_monitor2.joinable())
|
||||||
|
thread_monitor2.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sensor::isCoverClosed()
|
||||||
|
{
|
||||||
|
std::cout<<"isCoverClosed "<< coverPin.getValue()<<std::endl;
|
||||||
|
return coverPin.getValue() == Gpio::Low;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sensor::resetPaperPin()
|
||||||
|
{
|
||||||
|
scanPin.setDirection("in");
|
||||||
|
}
|
||||||
|
bool Sensor::isPaperStandby()
|
||||||
|
{
|
||||||
|
std::cout<<"isPaperStandby "<< paperPin.getValue()<<std::endl;
|
||||||
|
return paperPin.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sensor::isPaperAtScan()
|
||||||
|
{
|
||||||
|
//std::cout<<"scanPin "<< scanPin.getValue()<<std::endl;
|
||||||
|
return scanPin.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sensor::isDoublePaper()
|
||||||
|
{
|
||||||
|
return doubleEnablePin.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sensor::waitPaperIn(int timeout_ms)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(cv_m);
|
||||||
|
return cv_scan_at.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::no_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sensor::waitPaperOut(int timeout_ms)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(cv_m);
|
||||||
|
if (!isPaperIn())
|
||||||
|
{
|
||||||
|
LOG("scanPin Value is low! \n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
cv_scan_not_at.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::no_timeout;
|
||||||
|
return !isPaperIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sensor::waitPaperStandBy(int timeout_ms)
|
||||||
|
{
|
||||||
|
if(!paperPin.getValue()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(timeout_ms <= 0) {
|
||||||
|
return isPaperStandby();
|
||||||
|
}
|
||||||
|
std::unique_lock<std::mutex> lck(cv_m);
|
||||||
|
return cv_paper_on.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::no_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sensor::cancelWaitPaper()
|
||||||
|
{
|
||||||
|
cv_paper_on.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sensor::monitor()
|
||||||
|
{
|
||||||
|
std::condition_variable *edges[] = {&cv_scan_not_at, &cv_scan_at};
|
||||||
|
pollfd pfd;
|
||||||
|
int ret = 0;
|
||||||
|
pfd.fd = -1;
|
||||||
|
char buf[8];
|
||||||
|
int num;
|
||||||
|
pfd.fd = open(scanPin.getValuePath().c_str(), O_RDONLY);
|
||||||
|
if (pfd.fd < 0)
|
||||||
|
{
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pfd.events = POLLPRI;
|
||||||
|
StopWatch sw;
|
||||||
|
num = read(pfd.fd, buf, 8); // This is to clear the avaible read
|
||||||
|
std::cout<<"read time "<< sw.elapsed_ms()<<std::endl;
|
||||||
|
while (bMonitor)
|
||||||
|
{
|
||||||
|
ret = poll(&pfd, 1, 1000);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
if (pfd.revents & POLLPRI)
|
||||||
|
{
|
||||||
|
LOG(" ------------------------ scanpin running--------------------- \n");
|
||||||
|
lseek(pfd.fd, 0, SEEK_SET);
|
||||||
|
num = read(pfd.fd, buf, 8);
|
||||||
|
buf[num - 1] = '\0';
|
||||||
|
ret = atoi(buf);
|
||||||
|
//ftt.append_log(ret?"in":"out");
|
||||||
|
edges[ret]->notify_all();
|
||||||
|
LOG("\n *************scanpin %d time = %s ********* \n",ret,GetCurrentTimeStamp(2).c_str());
|
||||||
|
//sw.reset();
|
||||||
|
while(sw.elapsed_ms() < 10)
|
||||||
|
{
|
||||||
|
ret = poll(&pfd, 1, 1);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
num = read(pfd.fd, buf, 8);
|
||||||
|
buf[num - 1] = '\0';
|
||||||
|
ret = atoi(buf);
|
||||||
|
//printf("pMonitor nread = %d ret val = %d \n",num,ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(pfd.fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sensor::monitor2()
|
||||||
|
{
|
||||||
|
ScanEvent evts[] = {S_EVT_COVER_CLOSED, S_EVT_COVER_OPENED , S_EVT_PAPER_STANDBY, S_EVT_PAPER_NOT_STANDBY,
|
||||||
|
S_EVT_NOT_DOUBLEPAPER, S_EVT_DOUBLEPAPER, S_EVT_JAM_OUT, S_EVT_NORES};
|
||||||
|
std::vector<Gpio *> gpios;
|
||||||
|
gpios.push_back(&coverPin);
|
||||||
|
gpios.push_back(&paperPin);
|
||||||
|
//gpios.push_back(&double_out0_Pin);
|
||||||
|
//gpios.push_back(&double_out1_Pin);
|
||||||
|
std::vector<pollfd> pollfds;
|
||||||
|
pollfd pfd;
|
||||||
|
int ret = 0;
|
||||||
|
int fd = -1;
|
||||||
|
char buf[8];
|
||||||
|
int num;
|
||||||
|
LOG(" ------------------------ monitor2 running \n");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < gpios.size(); ++i)
|
||||||
|
{
|
||||||
|
fd = open(gpios[i]->getValuePath().c_str(), O_RDONLY);
|
||||||
|
LOG(" ------------------------ monitor2 open gpio[%d]=%s \n",i,gpios[i]->getValuePath().c_str());
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
ret = -1;
|
||||||
|
LOG(" ------------------------ monitor2 open break \n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pfd.fd = fd;
|
||||||
|
pfd.events = POLLPRI;
|
||||||
|
num = read(fd, buf, 8); // This is to clear the avaible read
|
||||||
|
pollfds.push_back(pfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(" ------------------------ monitor2 while running \n");
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
bMonitor2 = true;
|
||||||
|
while (bMonitor2)
|
||||||
|
{
|
||||||
|
static int poll_t = 0;
|
||||||
|
|
||||||
|
ret = poll(&pollfds[0], pollfds.size(), 1000);
|
||||||
|
//LOG(" ------------------------ monitor2 while running poll_t=%d ret=%d \n",++poll_t,ret);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < pollfds.size(); ++i)
|
||||||
|
{
|
||||||
|
if (pollfds[i].revents)
|
||||||
|
{
|
||||||
|
fd = pollfds[i].fd;
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
num = read(fd, buf, 8);
|
||||||
|
buf[num - 1] = '\0';
|
||||||
|
ret = atoi(buf);
|
||||||
|
LOG("event id : %d i= %d \n",evts[i * 2 + ret] , i );
|
||||||
|
if(evts[i * 2 + ret] == 272)
|
||||||
|
{
|
||||||
|
LOG("\n\n---------------double paper ----------------:%s \n\n", GetCurrentTimeStamp(2).c_str());
|
||||||
|
enableDoubleSensor(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i == 1)
|
||||||
|
{
|
||||||
|
LOG("paper sensor ret:%d \n", ret);
|
||||||
|
cv_paper_on.notify_all();
|
||||||
|
|
||||||
|
}
|
||||||
|
events.Put(evts[i * 2 + ret]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pollfds.size(); ++i)
|
||||||
|
{
|
||||||
|
close(pollfds[i].fd);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Gpio.h"
|
||||||
|
#include <thread>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include "BlockingQueue.h"
|
||||||
|
#include "FsmState.h"
|
||||||
|
#include "Pwm.h"
|
||||||
|
|
||||||
|
class Sensor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Sensor(BlockingQueue<ScanEvent>& sysEvents);
|
||||||
|
~Sensor();
|
||||||
|
|
||||||
|
void enableDoubleSensor(bool enable) {
|
||||||
|
doubleEnablePin.setValue((Gpio::GpioLevel)enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetPaperPin();
|
||||||
|
//是否扫描仪盖关上
|
||||||
|
bool isCoverClosed();
|
||||||
|
//是否纸张准备好
|
||||||
|
bool isPaperStandby();
|
||||||
|
//扫描时是否有纸张
|
||||||
|
bool isPaperAtScan();
|
||||||
|
//是否双张
|
||||||
|
bool isDoublePaper();
|
||||||
|
//等纸进来
|
||||||
|
bool waitPaperIn(int timeout_ms);
|
||||||
|
//等纸出去
|
||||||
|
bool waitPaperOut(int timeout_ms);
|
||||||
|
//纸在里面吗
|
||||||
|
bool isPaperIn(){return scanPin.getValue();}
|
||||||
|
//等纸,待命
|
||||||
|
bool waitPaperStandBy(int timeout_ms);
|
||||||
|
//取消等待纸张
|
||||||
|
void cancelWaitPaper();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Gpio coverPin; //开盖
|
||||||
|
Gpio paperPin; //有无纸
|
||||||
|
Gpio scanPin; //扫描传感器
|
||||||
|
Gpio double_out0_Pin;
|
||||||
|
Gpio double_out1_Pin;
|
||||||
|
Gpio doubleEnablePin;
|
||||||
|
Gpio sensor_power;
|
||||||
|
Pwm pwm2;
|
||||||
|
BlockingQueue<ScanEvent>& events;
|
||||||
|
std::mutex cv_m;
|
||||||
|
std::condition_variable cv_cover_opened;
|
||||||
|
std::condition_variable cv_cover_closed;
|
||||||
|
std::condition_variable cv_paper_on;
|
||||||
|
std::condition_variable cv_paper_off;
|
||||||
|
std::condition_variable cv_scan_at;
|
||||||
|
std::condition_variable cv_scan_not_at;
|
||||||
|
std::condition_variable cv_double;
|
||||||
|
std::thread thread_monitor;
|
||||||
|
std::thread thread_monitor2;
|
||||||
|
volatile bool bMonitor = true;
|
||||||
|
volatile bool bMonitor2 = true;
|
||||||
|
|
||||||
|
void monitor();
|
||||||
|
void monitor2();
|
||||||
|
};
|
|
@ -0,0 +1,208 @@
|
||||||
|
#include "SysInforTool.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
void get_system_output(char *cmd, char *output, int size)
|
||||||
|
{
|
||||||
|
FILE *fp = NULL;
|
||||||
|
fp = popen(cmd, "r");
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
if (fgets(output, size, fp) != NULL)
|
||||||
|
{
|
||||||
|
if (output[strlen(output) - 1] == '\n')
|
||||||
|
output[strlen(output) - 1] = '\0';
|
||||||
|
}
|
||||||
|
pclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*block to kbyte*/
|
||||||
|
unsigned long kscale(unsigned long m_block, unsigned long m_kbyte)
|
||||||
|
{
|
||||||
|
|
||||||
|
return ((unsigned long long)m_block * m_kbyte + 1024 / 2) / 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*convert size to GB MB KB*/
|
||||||
|
void convert_size(float m_size, int *dest)
|
||||||
|
{
|
||||||
|
if ((((m_size / 1024.0) / 1024.0)) >= 1.0)
|
||||||
|
{
|
||||||
|
*dest = (int)((m_size / 1024.0) / 1024.0);
|
||||||
|
}
|
||||||
|
else if ((m_size / 1024.0) >= 1.0)
|
||||||
|
{
|
||||||
|
*dest = (int)(m_size / 1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SysInforTool::SysInforTool(ScannerSysInfo tinfo)
|
||||||
|
{
|
||||||
|
m_sysinfo = tinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScannerSysInfo &SysInforTool::GetInfo()
|
||||||
|
{
|
||||||
|
return m_sysinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
SysInforTool::~SysInforTool()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*获取文件系统信息*/
|
||||||
|
int SysInforTool::get_fileSystem_info(const char *fileSystem_name, struct fileSystem_info *fi)
|
||||||
|
{
|
||||||
|
struct statfs buf;
|
||||||
|
float fileSystem_total_size = 0;
|
||||||
|
float fileSystem_free_size = 0;
|
||||||
|
|
||||||
|
if (statfs(fileSystem_name, &buf))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "statfs %s\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (buf.f_type)
|
||||||
|
{
|
||||||
|
case 0xEF51:
|
||||||
|
case 0xEF53:
|
||||||
|
sprintf(fi->fileSystem_format, "EXT");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4d44:
|
||||||
|
sprintf(fi->fileSystem_format, "FAT");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5346544e:
|
||||||
|
sprintf(fi->fileSystem_format, "NIFS");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sprintf(fi->fileSystem_format, "unknown");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bzero(&fi->fileSystem_total_capacity,sizeof(fi->fileSystem_total_capacity));
|
||||||
|
// bzero(&fi->fileSystem_free_capacity,sizeof(fi->fileSystem_free_capacity));
|
||||||
|
|
||||||
|
printf("blocks %ld\n", buf.f_blocks);
|
||||||
|
printf("bfree %ld\n", buf.f_bfree);
|
||||||
|
printf("bsize %ld\n", buf.f_bsize);
|
||||||
|
|
||||||
|
fileSystem_total_size =
|
||||||
|
(float)(kscale(buf.f_blocks, buf.f_bsize));
|
||||||
|
fileSystem_free_size =
|
||||||
|
(float)(kscale(buf.f_bfree, buf.f_bsize));
|
||||||
|
|
||||||
|
printf("total %f\n", fileSystem_total_size);
|
||||||
|
printf("free %f\n", fileSystem_free_size);
|
||||||
|
|
||||||
|
fi->fileSystem_total_capacity = fileSystem_total_size;
|
||||||
|
fi->fileSystem_free_capacity = fileSystem_free_size;
|
||||||
|
// convert_size(fileSystem_total_size,(int*)(&fi->fileSystem_total_capacity));
|
||||||
|
// convert_size(fileSystem_free_size,(int*)(&fi->fileSystem_free_capacity));
|
||||||
|
|
||||||
|
bzero(fi->fileSystem_permissions, sizeof(fi->fileSystem_permissions));
|
||||||
|
sprintf(fi->fileSystem_permissions, "rw");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int SysInforTool::GetMemTotal()
|
||||||
|
{
|
||||||
|
unsigned int totalmem=0;
|
||||||
|
struct sysinfo memInfo;
|
||||||
|
sysinfo(&memInfo);
|
||||||
|
return memInfo.totalram;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SysInforTool::IsSmallRam()
|
||||||
|
{
|
||||||
|
return GetMemTotal()<=2147483648;
|
||||||
|
}
|
||||||
|
std::string SysInforTool::GetSysInfo()
|
||||||
|
{
|
||||||
|
struct sysinfo memInfo;
|
||||||
|
sysinfo(&memInfo);
|
||||||
|
m_sysinfo.MemTotal = memInfo.totalram;
|
||||||
|
#ifdef G400
|
||||||
|
m_sysinfo.MemTotal > 2147483648 ? m_sysinfo.ResSup[2] = 600 : m_sysinfo.ResSup[2] = 0;
|
||||||
|
#else
|
||||||
|
if(m_sysinfo.FPGAVersion == 0x00060001)
|
||||||
|
{
|
||||||
|
m_sysinfo.ResSup[0] = 200;
|
||||||
|
m_sysinfo.ResSup[1] = m_sysinfo.ResSup[2]=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sysinfo.ResSup[0]= m_sysinfo.ResSup[1]= m_sysinfo.ResSup[2]=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
fileSystem_info fileinfo;
|
||||||
|
get_fileSystem_info("/", &fileinfo);
|
||||||
|
m_sysinfo.DiskTotal = fileinfo.fileSystem_total_capacity; // KB
|
||||||
|
m_sysinfo.DiskUsed = fileinfo.fileSystem_free_capacity; // KB
|
||||||
|
|
||||||
|
struct utsname t_uname;
|
||||||
|
if (uname(&t_uname) != 0)
|
||||||
|
perror("uname doesn't return 0, so there is an error");
|
||||||
|
|
||||||
|
printf("System Name = %s\n", t_uname.sysname);
|
||||||
|
printf("Node Name = %s\n", t_uname.nodename);
|
||||||
|
printf("Version = %s\n", t_uname.version);
|
||||||
|
printf("Release = %s\n", t_uname.release);
|
||||||
|
printf("Machine = %s\n", t_uname.machine);
|
||||||
|
if (strcmp(t_uname.nodename, "linaro-alip") == 0 && strcmp(t_uname.machine, "armv7l") == 0)
|
||||||
|
{
|
||||||
|
m_sysinfo.Systype = SysType::Sys_Linux_Debian;
|
||||||
|
m_sysinfo.CPU = SCPU::CPU_3288;
|
||||||
|
printf("Machine = %s CPU = %s \n", "Sys_Linux_Debian", "CPU_3288");
|
||||||
|
}
|
||||||
|
else if (strcmp(t_uname.nodename, "linaro-alip") == 0 && strcmp(t_uname.machine, "aarch64") == 0)
|
||||||
|
{
|
||||||
|
m_sysinfo.Systype = SysType::Sys_Linux_Debian;
|
||||||
|
m_sysinfo.CPU = SCPU::CPU_3399;
|
||||||
|
printf("Machine = %s CPU = %s \n", "Sys_Linux_Debian", "CPU_3399");
|
||||||
|
}
|
||||||
|
char output[512];
|
||||||
|
get_system_output("uname -a", output, sizeof(output));
|
||||||
|
std::string ver(output);
|
||||||
|
m_sysinfo.KernelVersion = ver;
|
||||||
|
printf("system version = %s \n", ver.c_str());
|
||||||
|
json j;
|
||||||
|
struct2json(j, m_sysinfo);
|
||||||
|
std::ofstream o("/usr/local/huago/sysinfo.json");
|
||||||
|
o << std::setw(4) << j << std::endl;
|
||||||
|
return j.dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysInforTool::struct2json(json &j, ScannerSysInfo &info)
|
||||||
|
{
|
||||||
|
j["CPU"] = info.CPU;
|
||||||
|
j["Systype"] = info.Systype;
|
||||||
|
j["Screentype"] = info.Screentype;
|
||||||
|
j["MtBoardVersion"] = info.MtBoardVersion;
|
||||||
|
j["MtType"] = info.MtType;
|
||||||
|
j["FPGAVersion"] = info.FPGAVersion;
|
||||||
|
j["Cistype"] = info.Cistype;
|
||||||
|
j["MaxRes"] = info.ResSup;
|
||||||
|
j["MemTotal"] = info.MemTotal;
|
||||||
|
j["DiskTotal"] = info.DiskTotal;
|
||||||
|
j["DiskUsed"] = info.DiskUsed;
|
||||||
|
j["KernelVersion"] = info.KernelVersion;
|
||||||
|
j["Have_EthernPort"] = info.Have_EthernPort;
|
||||||
|
j["ServiceVersion"] = info.ServiceVersion;
|
||||||
|
j["UsbProtocol"] = info.UsbProtocol;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
#include "scannersysinfo.h"
|
||||||
|
#include "json.hpp"
|
||||||
|
|
||||||
|
using json=nlohmann::json;
|
||||||
|
|
||||||
|
struct fileSystem_info{
|
||||||
|
char fileSystem_format[8];
|
||||||
|
unsigned int fileSystem_total_capacity;
|
||||||
|
unsigned int fileSystem_free_capacity;
|
||||||
|
char fileSystem_permissions[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SysInforTool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SysInforTool(ScannerSysInfo tinfo);
|
||||||
|
~SysInforTool();
|
||||||
|
std::string GetSysInfo();
|
||||||
|
ScannerSysInfo& GetInfo();
|
||||||
|
unsigned int GetMemTotal();
|
||||||
|
bool IsSmallRam();
|
||||||
|
private:
|
||||||
|
int get_fileSystem_info(const char *fileSystem_name,struct fileSystem_info *fi);
|
||||||
|
void struct2json(json& j,ScannerSysInfo& info);
|
||||||
|
private:
|
||||||
|
ScannerSysInfo m_sysinfo;
|
||||||
|
};
|
|
@ -0,0 +1,98 @@
|
||||||
|
#ifndef THREAD_POOL_H
|
||||||
|
#define THREAD_POOL_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <future>
|
||||||
|
#include <functional>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
class ThreadPool {
|
||||||
|
public:
|
||||||
|
ThreadPool(size_t);
|
||||||
|
template<class F, class... Args>
|
||||||
|
auto enqueue(F&& f, Args&&... args)
|
||||||
|
-> std::future<typename std::result_of<F(Args...)>::type>;
|
||||||
|
~ThreadPool();
|
||||||
|
private:
|
||||||
|
// need to keep track of threads so we can join them
|
||||||
|
std::vector< std::thread > workers;
|
||||||
|
// the task queue
|
||||||
|
std::queue< std::function<void()> > tasks;
|
||||||
|
|
||||||
|
// synchronization
|
||||||
|
std::mutex queue_mutex;
|
||||||
|
std::condition_variable condition;
|
||||||
|
bool stop;
|
||||||
|
};
|
||||||
|
|
||||||
|
// the constructor just launches some amount of workers
|
||||||
|
inline ThreadPool::ThreadPool(size_t threads)
|
||||||
|
: stop(false)
|
||||||
|
{
|
||||||
|
for(size_t i = 0;i<threads;++i)
|
||||||
|
workers.emplace_back(
|
||||||
|
[this]
|
||||||
|
{
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
std::function<void()> task;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(this->queue_mutex);
|
||||||
|
this->condition.wait(lock,
|
||||||
|
[this]{ return this->stop || !this->tasks.empty(); });
|
||||||
|
if(this->stop && this->tasks.empty())
|
||||||
|
return;
|
||||||
|
task = std::move(this->tasks.front());
|
||||||
|
this->tasks.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new work item to the pool
|
||||||
|
template<class F, class... Args>
|
||||||
|
auto ThreadPool::enqueue(F&& f, Args&&... args)
|
||||||
|
-> std::future<typename std::result_of<F(Args...)>::type>
|
||||||
|
{
|
||||||
|
using return_type = typename std::result_of<F(Args...)>::type;
|
||||||
|
|
||||||
|
auto task = std::make_shared< std::packaged_task<return_type()> >(
|
||||||
|
std::bind(std::forward<F>(f), std::forward<Args>(args)...)
|
||||||
|
);
|
||||||
|
|
||||||
|
std::future<return_type> res = task->get_future();
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(queue_mutex);
|
||||||
|
|
||||||
|
// don't allow enqueueing after stopping the pool
|
||||||
|
if(stop)
|
||||||
|
throw std::runtime_error("enqueue on stopped ThreadPool");
|
||||||
|
|
||||||
|
tasks.emplace([task](){ (*task)(); });
|
||||||
|
}
|
||||||
|
condition.notify_one();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the destructor joins all threads
|
||||||
|
inline ThreadPool::~ThreadPool()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(queue_mutex);
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
|
condition.notify_all();
|
||||||
|
for(std::thread &worker: workers)
|
||||||
|
worker.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include "TypeIO.h"
|
||||||
|
|
||||||
|
|
||||||
|
TypeIO::TypeIO(PORTS s0, PORTS s1, PORTS s2, PORTS s3) : gpio_s0(s0),
|
||||||
|
gpio_s1(s1),
|
||||||
|
gpio_s2(s2),
|
||||||
|
gpio_s3(s3)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeIO::~TypeIO()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CISVendor TypeIO::GetCisType()
|
||||||
|
{
|
||||||
|
auto s0 = gpio_s0.getValue();
|
||||||
|
auto s1 = gpio_s1.getValue();
|
||||||
|
auto s2 = gpio_s2.getValue();
|
||||||
|
auto s3 = gpio_s3.getValue();
|
||||||
|
std::string type;
|
||||||
|
CISVendor vender;
|
||||||
|
if (s0 == 0 && s1 == 0 && s2 == 0 && s3 == 1)
|
||||||
|
{
|
||||||
|
type = "DUNNAN_CIS_V0";
|
||||||
|
vender = CISVendor::DUNNAN_CIS_V0;
|
||||||
|
}
|
||||||
|
else if (s0 == 0 && s1 == 0 && s2 == 1 && s3 == 1)
|
||||||
|
{
|
||||||
|
type = "HUALIN_CIS_V0";
|
||||||
|
vender = CISVendor::HUALIN_CIS_V0;
|
||||||
|
}
|
||||||
|
else if (s0 == 0 && s1 == 0 && s2 == 0 && s3 == 0)
|
||||||
|
{
|
||||||
|
type = "DUNNAN_CIS_V0";
|
||||||
|
vender = CISVendor::DUNNAN_CIS_V0;
|
||||||
|
}
|
||||||
|
else if (s0 == 0 && s1 == 0 && s2 == 1 && s3 == 0)
|
||||||
|
{
|
||||||
|
type = "HUALIN_CIS_V0";
|
||||||
|
vender = CISVendor::HUALIN_CIS_V0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = "unknowun CIS TYPE";
|
||||||
|
vender = CISVendor::CIS_UNKNOWUN;
|
||||||
|
}
|
||||||
|
LOG("CIS Type :%s \n", type.c_str());
|
||||||
|
return vender;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMBType TypeIO::GetMotorType()
|
||||||
|
{
|
||||||
|
SMBType type = SMBType::MB_DRV_8825;
|
||||||
|
auto s0 = gpio_s0.getValue();
|
||||||
|
auto s1 = gpio_s1.getValue();
|
||||||
|
auto s2 = gpio_s2.getValue();
|
||||||
|
auto s3 = gpio_s3.getValue();
|
||||||
|
std::string typeinfo;
|
||||||
|
if (s0 == 0 && s1 == 0 && s2 == 0 && s3 == 1)
|
||||||
|
{
|
||||||
|
typeinfo = "MB_DRV_8825";
|
||||||
|
LOG("SMBType = MB_DRV_8825\n");
|
||||||
|
type = SMBType::MB_DRV_8825;
|
||||||
|
}
|
||||||
|
else if (s0 == 0 && s1 == 0 && s2 == 1 && s3 == 1)
|
||||||
|
{
|
||||||
|
typeinfo = "MB_DRV_8825";
|
||||||
|
LOG("SMBType = MB_DRV_8825\n");
|
||||||
|
type = SMBType::MB_DRV_8825;
|
||||||
|
}
|
||||||
|
else if (s0 == 0 && s1 == 0 && s2 == 0 && s3 == 0)
|
||||||
|
{
|
||||||
|
typeinfo = "MB_DRV_TMC216";
|
||||||
|
LOG("SMBType = MB_DRV_TMC216\n");
|
||||||
|
type = SMBType::MB_DRV_TMC216;
|
||||||
|
}
|
||||||
|
else if (s0 == 0 && s1 == 0 && s2 == 1 && s3 == 0)
|
||||||
|
{
|
||||||
|
typeinfo = "MB_DRV_TMC216";
|
||||||
|
LOG("SMBType = MB_DRV_TMC216\n");
|
||||||
|
type = SMBType::MB_DRV_TMC216;
|
||||||
|
type = SMBType::MB_DRV_TMC216;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typeinfo = "unknowun Motor TYPE";
|
||||||
|
LOG("SMBType =unknowun Motor TYPE\n");
|
||||||
|
type = SMBType::MB_DRV_UNKNOWUN;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Gpio.h"
|
||||||
|
#include "DevUtil.h"
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
#include <vector>
|
||||||
|
#include "scannersysinfo.h"
|
||||||
|
|
||||||
|
class TypeIO
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
public:
|
||||||
|
TypeIO(PORTS s0,PORTS s1,PORTS s2,PORTS s3);
|
||||||
|
CISVendor GetCisType();
|
||||||
|
SMBType GetMotorType();
|
||||||
|
~TypeIO();
|
||||||
|
private:
|
||||||
|
Gpio gpio_s0;
|
||||||
|
Gpio gpio_s1;
|
||||||
|
Gpio gpio_s2;
|
||||||
|
Gpio gpio_s3;
|
||||||
|
CISVendor cisven;
|
||||||
|
SMBType smbtype;
|
||||||
|
};
|
|
@ -0,0 +1,224 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int Command;
|
||||||
|
int Data;
|
||||||
|
int Length;
|
||||||
|
} USBCB;
|
||||||
|
|
||||||
|
enum class USBCommand : unsigned int
|
||||||
|
{
|
||||||
|
//无命令
|
||||||
|
NO_COMMAND = 0,
|
||||||
|
//获取dsp 状态
|
||||||
|
GET_DSP_STATUS = 1,
|
||||||
|
//取图
|
||||||
|
GET_IMAGE = 2,
|
||||||
|
//销毁DSP中驻存的图
|
||||||
|
POP_IMAGE = 3,
|
||||||
|
//开始扫描命令
|
||||||
|
START_COMMAND = 4,
|
||||||
|
//停止扫描命令
|
||||||
|
STOP = 5,
|
||||||
|
//获取扫描仪扫描模式
|
||||||
|
GET_SCAN_MODE = 6,
|
||||||
|
//获取固件版本号
|
||||||
|
GET_FW_VERSION = 7,
|
||||||
|
//返回PC端的状态
|
||||||
|
SEND_STATUS_PC = 8,
|
||||||
|
//下发扫描配置参数
|
||||||
|
CONFIGURED_DATA = 9,
|
||||||
|
//下发固件信息
|
||||||
|
SEND_FW = 10,
|
||||||
|
//获取扫描参数
|
||||||
|
GET_CONFIG_DATA = 11,
|
||||||
|
//获取扫描总张数
|
||||||
|
GET_SCANN_NUM = 12,
|
||||||
|
//获取有无纸的状态
|
||||||
|
GET_PAPERFEEDER_STATUS = 13,
|
||||||
|
//DSP初始化
|
||||||
|
INIT_HARDWARE_SYS = 14,
|
||||||
|
//下发元器件配置参数(灰度,LED R曝光时间)
|
||||||
|
SEND_COMPONENTS_GR = 15,
|
||||||
|
//下发元器件配置参数(LED G/B曝光时间)
|
||||||
|
SEND_COMPONENTS_GB = 16,
|
||||||
|
//下发扫描模式
|
||||||
|
SEND_SCAN_MODE = 17,
|
||||||
|
//开始进行平场矫正
|
||||||
|
START_FLAT = 18,
|
||||||
|
//停止平场矫正
|
||||||
|
STOP_FLAT = 19,
|
||||||
|
//下发200dpi彩色平场矫正参数
|
||||||
|
SEND_200_COLOR_FLAT_DATA = 20,
|
||||||
|
//下发300dpi彩色平场矫正参数
|
||||||
|
SEND_300_COLOR_FLAT_DATA = 21,
|
||||||
|
//获取200dpi彩色平场矫正参数
|
||||||
|
GET_200_COLOR_FLAT_DATA = 22,
|
||||||
|
//获取300dpi彩色平场矫正参数
|
||||||
|
GET_300_COLOR_FLAT_DATA = 23,
|
||||||
|
//下发200dpi灰度平场校正参数
|
||||||
|
SEND_200_GRAY_FLAT_DATA = 24,
|
||||||
|
//下发300dpi灰度平场校正参数
|
||||||
|
SEND_300_GRAY_FLAT_DATA = 25,
|
||||||
|
//获取200DPI灰度平场校正参数
|
||||||
|
GET_200_GRAY_FLAT_DATA = 26,
|
||||||
|
//获取300DPI灰度平场校正参数
|
||||||
|
GET_300_GRAY_FLAT_DATA = 27,
|
||||||
|
//下发序列号命令
|
||||||
|
SEND_SERIAL = 28,
|
||||||
|
//获取序列号命令
|
||||||
|
GET_SERIAL = 29,
|
||||||
|
//获取滚轴数
|
||||||
|
GET_ROLLER_NUM = 0x1e,
|
||||||
|
//清零滚轴数
|
||||||
|
CLR_ROLLER_NUM = 0x1f,
|
||||||
|
//清除扫描总张数
|
||||||
|
CLR_SCAN_NUM = 0x20,
|
||||||
|
//准备更新固件
|
||||||
|
PRE_UPGRADE = 0X21,
|
||||||
|
//开始更新固件
|
||||||
|
START_UPGRADE = 0x22,
|
||||||
|
//彩色的AD参数
|
||||||
|
RGB_ADI_PARA = 0x23,
|
||||||
|
//灰度的AD参数
|
||||||
|
ADI_PARA = 0x24,
|
||||||
|
//获取CIS参数(曝光时间,ad参数)
|
||||||
|
GET_CIS_PARA = 0x25,
|
||||||
|
//扫描张数
|
||||||
|
START_COMMAND_COUNT = 0x26,
|
||||||
|
//下发休眠时间
|
||||||
|
SET_SLEEP_TIME = 0x27,
|
||||||
|
//获取休眠时间
|
||||||
|
GET_SLEEP_TIME = 0x28,
|
||||||
|
//清除缓存
|
||||||
|
CLR_CACHE = 0x29,
|
||||||
|
//下发速度模式
|
||||||
|
SET_SPEED_MODE = 0x2a,
|
||||||
|
//获取扫描速度模式
|
||||||
|
GET_SPEED_MODE = 0X2b,
|
||||||
|
//设置固件版本一共8个字节
|
||||||
|
SET_FW_VERSION = 0X2c,
|
||||||
|
//获取DSP版本
|
||||||
|
GET_DSP_VERSION = 0X2d,
|
||||||
|
//采集板FPGA固件版本
|
||||||
|
GET_SCANFPGA_VERSION = 0x2e,
|
||||||
|
//电机板FPGA固件版本
|
||||||
|
GET_MOTORFPGA_VERSION = 0X2f,
|
||||||
|
//设置制造商信息
|
||||||
|
SET_USB_INFOR_MANUFACTURE = 0X30,
|
||||||
|
//获取制造商信息
|
||||||
|
GET_USB_INFOR_MANUFACTURE = 0X31,
|
||||||
|
//设置产品型号信息
|
||||||
|
SET_USB_INFOR_MODEL_NAME = 0X32,
|
||||||
|
//获取产品型号信息
|
||||||
|
GET_USB_INFOR_MODEL_NAME = 0X33,
|
||||||
|
//设置USB PID / VID信息
|
||||||
|
SET_USB_INFOR_VIDPID = 0X34,
|
||||||
|
GET_USB_INFOR_VIDPID = 0X35,
|
||||||
|
//设置卡纸急停检测灵敏度
|
||||||
|
SET_JAM_DETECT_SENSITIVE = 0X36,
|
||||||
|
//获取卡纸急停检测灵敏度
|
||||||
|
GET_JAM_DETECT_SENSITIVE = 0X37,
|
||||||
|
//设置横向畸变系数
|
||||||
|
SET_JUST_COF_H = 0x38,
|
||||||
|
//读取横向畸变系数
|
||||||
|
GET_JUST_COF_H = 0x39,
|
||||||
|
//G400 清除硬件异常
|
||||||
|
CLEAR_HWERROR = 0x40,
|
||||||
|
//设置纵向畸变系数
|
||||||
|
SET_JUST_COF_V = 0x41,
|
||||||
|
//读取纵向畸变系数
|
||||||
|
GET_JUST_COF_V = 0x42,
|
||||||
|
//设置彩色校正参数
|
||||||
|
SEND_COLOR_FLAT = 0x43,
|
||||||
|
//设置彩色平场校正参数
|
||||||
|
SEND_COLORCORRECT_FLAT = 0x44,
|
||||||
|
//设置灰度校正参数
|
||||||
|
SEND_GRAY_FLAT = 0x45,
|
||||||
|
//设置灰度平场校正参数
|
||||||
|
SEND_GRAYCORRECT_FLAT = 0x46,
|
||||||
|
//设置平场校正参数
|
||||||
|
GET_FLAT_DATA =0x47,
|
||||||
|
//更新完成
|
||||||
|
UPDATE_FINISHED = 0x48,
|
||||||
|
//重启
|
||||||
|
REBOOT = 0x49,
|
||||||
|
//获取日志
|
||||||
|
GET_LOG_FILES_INFO = 0x50,
|
||||||
|
//发送log文件完成
|
||||||
|
GET_UPDATE_RESULT=0x51,
|
||||||
|
//清空日志
|
||||||
|
CLEAR_LOG_FILES = 0x52,
|
||||||
|
//获取搓纸失败
|
||||||
|
GET_CUO_ERROR,
|
||||||
|
//获取双张失败次数
|
||||||
|
GET_DOU_ERROR,
|
||||||
|
//获取卡纸次数
|
||||||
|
GET_JAM_ERROR,
|
||||||
|
ACTIVE_SCANNER=0x100,
|
||||||
|
//图像处理参数下发
|
||||||
|
GETSYSINFO_LEN =0x200,
|
||||||
|
GETSYSINFO =0x201,
|
||||||
|
GETMOTORPARAM = 0x202,
|
||||||
|
GETMOTORPARMLEN=0x203,
|
||||||
|
SETMOTORPARAM = 0x204,
|
||||||
|
SETMOTORPARAMLEN =0x205
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class HG_ScannerStatus
|
||||||
|
{
|
||||||
|
//异常
|
||||||
|
HAVE_ERROR = -1,
|
||||||
|
//正常状态
|
||||||
|
NORMAL = 0,
|
||||||
|
//开盖
|
||||||
|
OPEN_COVER = 1,
|
||||||
|
// 无纸
|
||||||
|
NO_FEED = 2,
|
||||||
|
// 搓纸失败
|
||||||
|
FEED_IN_ERROR = 4,
|
||||||
|
// 卡纸
|
||||||
|
PAPER_JAM = 8,
|
||||||
|
// 检测到双张
|
||||||
|
DETECT_DOUBLE_FEED = 16,
|
||||||
|
// 检测到订书钉
|
||||||
|
DETECT_STAPLE = 32,
|
||||||
|
// 纸张倾斜
|
||||||
|
PAPER_SKEW = 64,
|
||||||
|
// 自动模式
|
||||||
|
AUTO_SCAN_MODE = 65,
|
||||||
|
// 手动模式
|
||||||
|
MANAUL_SCAN_MODE = 66,
|
||||||
|
// 计数模式
|
||||||
|
COUNT_MODE = 67,
|
||||||
|
// 硬件错误
|
||||||
|
HARDWARE_ERROR = 68,
|
||||||
|
// FPGA崩溃
|
||||||
|
FPGA_ERROR = 68,
|
||||||
|
// 开始
|
||||||
|
START_SCAN = 69,
|
||||||
|
//停止
|
||||||
|
STOP_SCAN = 70,
|
||||||
|
//有图
|
||||||
|
HAVE_IMAGE = 71,
|
||||||
|
// 更新扫描参数
|
||||||
|
UPDATE_SCAN_PARAMETER = 72,
|
||||||
|
// PC繁忙或出错
|
||||||
|
PC_SCAN_BUSY_or_ERROR = 73,
|
||||||
|
// 更新完成
|
||||||
|
UPDATE_FINISHED = 74,
|
||||||
|
//尺寸检测错误
|
||||||
|
SIZE_ERROR=75,
|
||||||
|
//纸张有孔
|
||||||
|
PAPER_HOLE = 84,
|
||||||
|
//自动校正中
|
||||||
|
AUTO_FLATTING=198,
|
||||||
|
//USB 未连接
|
||||||
|
USB_DISCONNECTED = 200,
|
||||||
|
//用户点击停止
|
||||||
|
USER_STOP = 201,
|
||||||
|
//自动平场校正完成
|
||||||
|
AUTO_FLAT_FINISHED = 202,
|
||||||
|
SCANNER_ACTIVED=0x10
|
||||||
|
};
|
|
@ -0,0 +1,86 @@
|
||||||
|
#include "UsbEndpoint.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
extern int errno;
|
||||||
|
|
||||||
|
UsbEndPoint::UsbEndPoint(EndpointType eptype):m_fd(-1)
|
||||||
|
{
|
||||||
|
m_endpointtype=eptype;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsbEndPoint::~UsbEndPoint()
|
||||||
|
{
|
||||||
|
if(m_fd)
|
||||||
|
{
|
||||||
|
::close(m_fd);
|
||||||
|
LOG("try close %s \n",map_endpoints[m_endpointtype].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int UsbEndPoint::open()
|
||||||
|
{
|
||||||
|
int ret=(int)HGUSB_ErrorCode::HG_USBSuccess;
|
||||||
|
if(m_endpointtype!=EndpointType::EP_Undefine)
|
||||||
|
{
|
||||||
|
LOG("try open %s \n",map_endpoints[m_endpointtype].c_str());
|
||||||
|
m_fd = ::open(map_endpoints[m_endpointtype].c_str(),O_RDWR);
|
||||||
|
if(m_fd ==-1)
|
||||||
|
{
|
||||||
|
ret=(int)HGUSB_ErrorCode::HG_USBOpenFailed;
|
||||||
|
LOG("try open %s fialed errorcode %d \n",map_endpoints[m_endpointtype].c_str(),errno);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG("try open %s success \n",map_endpoints[m_endpointtype].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbEndPoint::close()
|
||||||
|
{
|
||||||
|
if(m_fd)
|
||||||
|
{
|
||||||
|
::close(m_fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int UsbEndPoint::read(void* pdata,int length)
|
||||||
|
{
|
||||||
|
int ret = (int)HGUSB_ErrorCode::HG_USBSuccess;
|
||||||
|
if(!pdata)
|
||||||
|
return (int)HGUSB_ErrorCode::HG_USBInvalidePtr;
|
||||||
|
|
||||||
|
if(m_fd!=-1)
|
||||||
|
{
|
||||||
|
//DEBUG("try reading USB %s endpoint data\n",map_endpoints[m_endpointtype].c_str());
|
||||||
|
return ::read(m_fd,pdata,length);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UsbEndPoint::write(void* pdata,int length)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if(!pdata)
|
||||||
|
return (int)HGUSB_ErrorCode::HG_USBInvalidePtr;
|
||||||
|
|
||||||
|
if(m_fd!=-1)
|
||||||
|
{
|
||||||
|
//DEBUG("try writing USB %s endpoint data\n",map_endpoints[m_endpointtype].c_str());
|
||||||
|
return ::write(m_fd,pdata,length);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UsbEndPoint::getEndpointType()
|
||||||
|
{
|
||||||
|
return (int)m_endpointtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UsbEndPoint::is_open()
|
||||||
|
{
|
||||||
|
return m_fd != -1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ====================================================
|
||||||
|
|
||||||
|
* 功能:linux USB device USB通信 底层端点抽象
|
||||||
|
* 作者:彭明
|
||||||
|
* 生成时间:2020/8/18
|
||||||
|
* 版本号:v1.0
|
||||||
|
|
||||||
|
* ====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IUSBENDPOINT_H
|
||||||
|
#define IUSBENDPOINT_H
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <map>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "scanservices_utils.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
enum class HGUSB_ErrorCode
|
||||||
|
{
|
||||||
|
HG_USBSuccess=-1,
|
||||||
|
HG_USBOpenFailed,
|
||||||
|
HG_USBInvalidePtr,
|
||||||
|
HG_USBPCUnConnected
|
||||||
|
};
|
||||||
|
|
||||||
|
class UsbEndPoint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class EndpointType
|
||||||
|
{
|
||||||
|
EP_Undefine,
|
||||||
|
EP_Control,
|
||||||
|
EP_Bulk_In,
|
||||||
|
EP_Bulk_Out,
|
||||||
|
Ep_Int
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
UsbEndPoint(EndpointType eptype);
|
||||||
|
~UsbEndPoint();
|
||||||
|
int open();
|
||||||
|
void close();
|
||||||
|
int read(void* pdata,int length);
|
||||||
|
int write(void* pdata,int length);
|
||||||
|
int getEndpointType();
|
||||||
|
bool is_open();
|
||||||
|
private:
|
||||||
|
int m_fd;
|
||||||
|
EndpointType m_endpointtype;
|
||||||
|
std::map<EndpointType,std::string> map_endpoints={
|
||||||
|
{EndpointType::EP_Bulk_In,BULK_IN_PATH},
|
||||||
|
{EndpointType::EP_Bulk_Out,BULK_OUT_PATH},
|
||||||
|
{EndpointType::EP_Control,BULK_CTL_PATH},
|
||||||
|
{EndpointType::Ep_Int,BULK_INT_PATH}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //IUSBENDPOINT_H
|
|
@ -0,0 +1,548 @@
|
||||||
|
#include "UsbScanner.h"
|
||||||
|
#include <turbojpeg.h>
|
||||||
|
#include "JsonConfig.h"
|
||||||
|
#include "USBProtocol.h"
|
||||||
|
|
||||||
|
#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 int enqueueindex = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const int SPEED_MODE_MAX = 5;
|
||||||
|
UsbScanner::UsbScanner() : m_startscan(false),
|
||||||
|
imageremain(0),
|
||||||
|
eventsramain(0)
|
||||||
|
{
|
||||||
|
DeviceExport();
|
||||||
|
m_serial = ("G20018000298OO");
|
||||||
|
m_fwversion = ("12345613");
|
||||||
|
mount_usb_device();
|
||||||
|
printf("mount usb ing \n");
|
||||||
|
auto ctrl_req_handler = [&](int fd, struct usb_ctrlrequest *setup, unsigned char *buffer) -> bool
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (regindex < 0 || regindex >= 18)
|
||||||
|
return false;
|
||||||
|
unsigned int regv = m_hgScanner->readreg(regindex);
|
||||||
|
memcpy(buffer, ®v, sizeof(regv));
|
||||||
|
::write(fd, buffer, setup->wLength);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case USB_REQ_SET_FPGA_REGS:
|
||||||
|
if (!(setup->bRequestType & USB_DIR_IN) && creg)
|
||||||
|
{
|
||||||
|
::read(fd, buffer, setup->wLength);
|
||||||
|
|
||||||
|
LOG("USB_REQ_SET_FPGA_REGS set val = %d \n", *(unsigned int *)buffer);
|
||||||
|
// if (!write_regs(regs, regindex, creg, this->fgparegs))
|
||||||
|
// return false;
|
||||||
|
/*
|
||||||
|
暂时不响应上层配置fpga寄存器操作,仅将数据读出来;
|
||||||
|
*/
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_GET_MOTOR_REGS:
|
||||||
|
if ((setup->bRequestType & USB_DIR_IN))
|
||||||
|
{
|
||||||
|
// 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))
|
||||||
|
{
|
||||||
|
::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 hotplug_handler = [&](bool isconnect)
|
||||||
|
{
|
||||||
|
LOG("usb hotplug_handler is connect : %s \n", isconnect ? "true" : "false");
|
||||||
|
};
|
||||||
|
|
||||||
|
m_usb.reset(new UsbDevice(ctrl_req_handler, hotplug_handler));
|
||||||
|
// m_usb.get();
|
||||||
|
auto imageready = [this](const HG_JpegCompressInfo &imageinfo)
|
||||||
|
{
|
||||||
|
imageremain++;
|
||||||
|
m_images.Put(imageinfo);
|
||||||
|
// LOG("Enqueue image index :%d ptr:%p length:%d\n", ++enqueueindex,imageinfo.pJpegData, imageinfo.DataLength);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto deviceevent = [this](const int eventID, std::string capmsg)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOG("\n 222222222 Enqueue event %d \n", eventID);
|
||||||
|
eventsramain++;
|
||||||
|
// unsigned char buff[64]={0};
|
||||||
|
|
||||||
|
//printf("--------------------------66 = %d\r\n",eventsramain);
|
||||||
|
m_scannerEvents.Put({eventID, capmsg});
|
||||||
|
if (eventID == (int)HG_ScannerStatus::STOP_SCAN)
|
||||||
|
{
|
||||||
|
m_startscan = false;
|
||||||
|
writesyslog(LOG_INFO, getmeminfo());
|
||||||
|
}
|
||||||
|
if (eventID == (int)(HG_ScannerStatus::AUTO_FLAT_FINISHED))
|
||||||
|
{
|
||||||
|
m_hgScanner->ResetCorrectflags();
|
||||||
|
}
|
||||||
|
else if ((eventID == (int)HG_ScannerStatus::SIZE_ERROR) || (eventID == (int)HG_ScannerStatus::PAPER_HOLE))
|
||||||
|
{
|
||||||
|
m_hgScanner->StopScan(0);
|
||||||
|
// m_usb->
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ScannerGlue glue = {imageready, deviceevent};
|
||||||
|
m_hgScanner.reset(new Scanner(glue));
|
||||||
|
}
|
||||||
|
|
||||||
|
UsbScanner::~UsbScanner()
|
||||||
|
{
|
||||||
|
if (!m_images.IsShutDown())
|
||||||
|
m_images.ShutDown();
|
||||||
|
|
||||||
|
if (!m_scannerEvents.IsShutDown())
|
||||||
|
m_scannerEvents.ShutDown();
|
||||||
|
|
||||||
|
if (m_hgScanner.get())
|
||||||
|
m_hgScanner.reset();
|
||||||
|
|
||||||
|
if(m_usb.get())
|
||||||
|
m_usb.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::StartScan(int scancount)
|
||||||
|
{
|
||||||
|
ClearImages();
|
||||||
|
LOG("m_scannerEvents size %d\n", m_scannerEvents.Size());
|
||||||
|
ClearErrorEvents();
|
||||||
|
LOG("m_images size %d\n", m_images.Size());
|
||||||
|
m_hgScanner->SetDstScanNum(9999);//scancount <= 0 ? 1 : scancount);
|
||||||
|
printf("1111111111111111111 %d \r\n", scancount);
|
||||||
|
m_hgScanner->put(S_EVT_START_SCAN);
|
||||||
|
// m_hgScanner->startScan();
|
||||||
|
LOG("Put Event S_EVT_START_SCAN\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::StopScan()
|
||||||
|
{
|
||||||
|
m_hgScanner->put(S_EVT_STOP_SCAN);
|
||||||
|
LOG("Put Event S_EVT_STOP_SCAN\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::ConfigScanParam(HG_ScanConfiguration config)
|
||||||
|
{
|
||||||
|
m_startscan = true;
|
||||||
|
imageremain = 0;
|
||||||
|
eventsramain = 0;
|
||||||
|
m_hgScanner->ConfigScanParam(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UsbScanner::FeederLoaded()
|
||||||
|
{
|
||||||
|
return m_hgScanner->isFeederLoaded();
|
||||||
|
}
|
||||||
|
std::string UsbScanner::GetSerial()
|
||||||
|
{
|
||||||
|
auto info = GetScanInfoFromJson();
|
||||||
|
return info.SerialNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::SetSerial(std::string serial)
|
||||||
|
{
|
||||||
|
if (m_serial.length() != 14)
|
||||||
|
{
|
||||||
|
LOG("SetSerial error length,length must be 14 \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_serial = serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UsbScanner::GetFWVersion()
|
||||||
|
{
|
||||||
|
LOG(" GetFWVersion----------------- \n");
|
||||||
|
// JsonConfig js;
|
||||||
|
auto info = js_config.GetScanInfo();
|
||||||
|
return mapFradme_SP[info.SpeedMode].FWVERSIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::SetFwVersion(std::string fwversion)
|
||||||
|
{
|
||||||
|
if (fwversion.length() != 10)
|
||||||
|
{
|
||||||
|
LOG("SetFwVersion error length \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_fwversion = fwversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UsbScanner::GetRollerNum()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::ClearRollerNum()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::InitScanner()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::ClearImages()
|
||||||
|
{
|
||||||
|
while (m_images.Size() > 0)
|
||||||
|
{
|
||||||
|
auto jpeg = m_images.Take();
|
||||||
|
// tjFree(jpeg.pJpegData);
|
||||||
|
}
|
||||||
|
imageremain = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aquiredimgindex = 0;
|
||||||
|
HG_JpegCompressInfo UsbScanner::GetImage()
|
||||||
|
{
|
||||||
|
HG_JpegCompressInfo ret = {nullptr, 0};
|
||||||
|
if (m_images.Size() > 0 && !m_images.IsShutDown())
|
||||||
|
{
|
||||||
|
ret = m_images.Take();
|
||||||
|
imageremain--;
|
||||||
|
// LOG("aquired image index %d \n",++aquiredimgindex);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
HG_Msg UsbScanner::GetEvent()
|
||||||
|
{
|
||||||
|
HG_Msg ret = {(int)HG_ScannerStatus::NORMAL, ""};
|
||||||
|
if (m_scannerEvents.Size() > 0 && !m_scannerEvents.IsShutDown())
|
||||||
|
{
|
||||||
|
ret = m_scannerEvents.Take();
|
||||||
|
eventsramain--;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::ClearErrorEvents()
|
||||||
|
{
|
||||||
|
while (m_scannerEvents.Size() > 0)
|
||||||
|
{
|
||||||
|
m_scannerEvents.Take();
|
||||||
|
}
|
||||||
|
eventsramain = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::ClearHWError()
|
||||||
|
{
|
||||||
|
m_hgScanner->put(S_EVT_CLEAR_ERR);
|
||||||
|
LOG("Put Event S_EVT_CLEAR_ERR\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UsbScanner::GetImagequeueEmpty()
|
||||||
|
{
|
||||||
|
return imageremain == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UsbScanner::GetEventQueueEmpty()
|
||||||
|
{
|
||||||
|
return eventsramain == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HG_JpegCompressInfo UsbScanner::GetFrontImage()
|
||||||
|
{
|
||||||
|
HG_JpegCompressInfo ret = {nullptr, 0};
|
||||||
|
if (m_images.Size() > 0)
|
||||||
|
ret = m_images.Front();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
HG_Msg UsbScanner::GetEventFront()
|
||||||
|
{
|
||||||
|
HG_Msg ret = {(int)HG_ScannerStatus::NORMAL, ""};
|
||||||
|
if (m_scannerEvents.Size() > 0 && !m_scannerEvents.IsShutDown())
|
||||||
|
{
|
||||||
|
ret = m_scannerEvents.Front();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::CreatCorrectData(int correctmode)
|
||||||
|
{
|
||||||
|
ClearErrorEvents();
|
||||||
|
m_hgScanner->CreatCorrectData(correctmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UsbScanner::IsScanning()
|
||||||
|
{
|
||||||
|
return m_hgScanner->IsScanning();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::SetFlatParam(int type, int *value)
|
||||||
|
{
|
||||||
|
std::string ttype;
|
||||||
|
switch ((USBCommand)type)
|
||||||
|
{
|
||||||
|
case USBCommand::SEND_COLOR_FLAT:
|
||||||
|
ttype = "color";
|
||||||
|
break;
|
||||||
|
case USBCommand::SEND_COLORCORRECT_FLAT:
|
||||||
|
ttype = "correctColor";
|
||||||
|
break;
|
||||||
|
case USBCommand::SEND_GRAY_FLAT:
|
||||||
|
ttype = "gray";
|
||||||
|
break;
|
||||||
|
case USBCommand::SEND_GRAYCORRECT_FLAT:
|
||||||
|
ttype = "correctGray";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!ttype.empty())
|
||||||
|
m_hgScanner->writeParamars(ttype, value);
|
||||||
|
}
|
||||||
|
CaptureParams UsbScanner::GetCaptureParams()
|
||||||
|
{
|
||||||
|
return m_hgScanner->GetCaptureParams();
|
||||||
|
}
|
||||||
|
void UsbScanner::UpdateScanInfo(int type, void *data)
|
||||||
|
{
|
||||||
|
auto info = GetScanInfoFromJson();
|
||||||
|
switch ((USBCommand)type)
|
||||||
|
{
|
||||||
|
case USBCommand::SEND_SERIAL:
|
||||||
|
{
|
||||||
|
char serial[15];
|
||||||
|
serial[14] = '\0';
|
||||||
|
memcpy(serial, data, 14);
|
||||||
|
std::string serial_s(serial);
|
||||||
|
m_hgScanner->GetScanInfo().SerialNum = serial_s;
|
||||||
|
info.SerialNum = serial_s;
|
||||||
|
SaveScaninfo(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case USBCommand::SET_JUST_COF_H:
|
||||||
|
info.HRatio = *(unsigned int *)(data);
|
||||||
|
break;
|
||||||
|
case USBCommand::SET_JUST_COF_V:
|
||||||
|
info.VRatio = *(unsigned int *)(data);
|
||||||
|
printf("SET_JUST_COF_V = %d %f\n", info.VRatio, *(float *)(data));
|
||||||
|
break;
|
||||||
|
case USBCommand::CLR_ROLLER_NUM:
|
||||||
|
info.RollerNum = 0;
|
||||||
|
break;
|
||||||
|
case USBCommand::CLR_SCAN_NUM:
|
||||||
|
info.TotalScanned = 0;
|
||||||
|
break;
|
||||||
|
case USBCommand::SET_SLEEP_TIME:
|
||||||
|
info.SleepTime = *(unsigned int *)(data);
|
||||||
|
printf("set sleep time = %d \n", info.SleepTime);
|
||||||
|
SaveScaninfo(info);
|
||||||
|
stop_countdown();
|
||||||
|
start_enter_lowpwoer();
|
||||||
|
return;
|
||||||
|
case USBCommand::SET_SPEED_MODE:
|
||||||
|
if (*(unsigned int *)(data) > SPEED_MODE_MAX)
|
||||||
|
{
|
||||||
|
info.SpeedMode = 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.SpeedMode = *(unsigned int *)(data);
|
||||||
|
}
|
||||||
|
LOG("UsbScanner SET SpeedMode == %d------ \n", info.SpeedMode);
|
||||||
|
iter = mapFradme_SP.find(info.SpeedMode);
|
||||||
|
if (iter != mapFradme_SP.end())
|
||||||
|
info.FWVersion = iter->second.FWVERSIO;
|
||||||
|
SaveScaninfo(info);
|
||||||
|
m_hgScanner->updateSpeedMode(info.SpeedMode);
|
||||||
|
LOG("UsbScanner SET SpeedMode == %d-------info.FWVersion = %s \n", info.SpeedMode, info.FWVersion.c_str());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SaveScaninfo(info);
|
||||||
|
m_hgScanner->UpdateScanInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
ScannerScanInfo UsbScanner::GetScanInfo()
|
||||||
|
{
|
||||||
|
return m_hgScanner->GetScanInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsbScanner::SetLEDStatus(LedStatus status)
|
||||||
|
{
|
||||||
|
m_hgScanner->getPanelLeds().setStatus(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UsbScanner::GetSysInfo()
|
||||||
|
{
|
||||||
|
return m_hgScanner->GetSysInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
int UsbScanner::read_bulk(void *pdata, int length)
|
||||||
|
{
|
||||||
|
int ret=0;
|
||||||
|
|
||||||
|
if(pdata==nullptr || length == 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if(m_usb.get()&& m_usb->is_connected())
|
||||||
|
{
|
||||||
|
ret = m_usb->read_bulk(pdata,length,1000);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
int UsbScanner::write_bulk(void *pdata, int length)
|
||||||
|
{
|
||||||
|
int ret=0;
|
||||||
|
|
||||||
|
if(pdata==nullptr || length == 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if(m_usb.get()&& m_usb->is_connected())
|
||||||
|
{
|
||||||
|
ret = m_usb->write_bulk(pdata,length);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UsbScanner::is_connect()
|
||||||
|
{
|
||||||
|
if(!m_usb.get())
|
||||||
|
return false;
|
||||||
|
return m_usb->is_connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UsbScanner::mount_usb_device()
|
||||||
|
{
|
||||||
|
if ((access("/dev/ffs-camtp/ep0", F_OK)) != -1)
|
||||||
|
return;
|
||||||
|
int result = system("modprobe libcomposite\n \
|
||||||
|
mkdir /var/cfg\n \
|
||||||
|
mount none /var/cfg -t configfs\n \
|
||||||
|
mkdir /var/cfg/usb_gadget/g1\n \
|
||||||
|
cd /var/cfg/usb_gadget/g1\n \
|
||||||
|
mkdir configs/c.1 \n \
|
||||||
|
mkdir functions/ffs.camtp\n \
|
||||||
|
mkdir strings/0x409\n \
|
||||||
|
mkdir configs/c.1/strings/0x409\n \
|
||||||
|
echo 0x0300 > idProduct\n \
|
||||||
|
echo 0x3072 > idVendor\n \
|
||||||
|
echo \"01234567AABBCCDDEE\" > strings/0x409/serialnumber\n \
|
||||||
|
echo \"Holdtecs Technologies\" > strings/0x409/manufacturer\n \
|
||||||
|
echo \"The Holdtecs Product !\" > strings/0x409/product\n \
|
||||||
|
echo \"Conf 1\" > configs/c.1/strings/0x409/configuration\n \
|
||||||
|
echo 120 > configs/c.1/MaxPower\n \
|
||||||
|
ln -s functions/ffs.camtp configs/c.1\n \
|
||||||
|
mkdir /dev/ffs-camtp\n \
|
||||||
|
mount -t functionfs camtp /dev/ffs-camtp");
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#pragma once
|
||||||
|
#include "IScanner.h"
|
||||||
|
#include "Scanner.h"
|
||||||
|
#include <memory>
|
||||||
|
#include "FsmState.h"
|
||||||
|
#include "usbdevice.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class UsbScanner : public IScanner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UsbScanner();
|
||||||
|
virtual ~UsbScanner();
|
||||||
|
virtual void StartScan(int scancount) override;
|
||||||
|
virtual void StopScan() override;
|
||||||
|
virtual void ConfigScanParam(HG_ScanConfiguration config) override;
|
||||||
|
virtual bool FeederLoaded() override;
|
||||||
|
virtual std::string GetSerial() override;
|
||||||
|
virtual void SetSerial(std::string serial) override;
|
||||||
|
virtual std::string GetFWVersion() override;
|
||||||
|
virtual void SetFwVersion(std::string fwversion) override;
|
||||||
|
virtual int GetRollerNum() override;
|
||||||
|
virtual void ClearRollerNum() override;
|
||||||
|
virtual void InitScanner() override;
|
||||||
|
virtual void ClearImages() override;
|
||||||
|
virtual HG_JpegCompressInfo GetImage() override;
|
||||||
|
virtual HG_Msg GetEvent() override;
|
||||||
|
virtual void ClearErrorEvents() override;
|
||||||
|
virtual void ClearHWError() override;
|
||||||
|
virtual bool GetImagequeueEmpty() override;
|
||||||
|
virtual bool GetEventQueueEmpty() override;
|
||||||
|
virtual HG_JpegCompressInfo GetFrontImage() override;
|
||||||
|
virtual HG_Msg GetEventFront() override;
|
||||||
|
virtual void CreatCorrectData(int correctmode) override;
|
||||||
|
virtual bool IsScanning() override;
|
||||||
|
virtual void SetFlatParam(int type,int* value) override;
|
||||||
|
virtual CaptureParams GetCaptureParams() override;
|
||||||
|
virtual void UpdateScanInfo(int type,void* data) override;
|
||||||
|
virtual ScannerScanInfo GetScanInfo() override;
|
||||||
|
virtual void SetLEDStatus(LedStatus status) override;
|
||||||
|
std::string GetSysInfo();
|
||||||
|
int read_bulk(void *pdata, int length);
|
||||||
|
int write_bulk(void *pdata, int length);
|
||||||
|
bool is_connect();
|
||||||
|
private:
|
||||||
|
void mount_usb_device();
|
||||||
|
|
||||||
|
private:
|
||||||
|
map<int, sp_COLOR_or_GRAY >::iterator iter;
|
||||||
|
std::shared_ptr<Scanner> m_hgScanner;
|
||||||
|
std::shared_ptr<UsbDevice> m_usb;
|
||||||
|
bool m_startscan;
|
||||||
|
volatile int imageremain;
|
||||||
|
volatile int eventsramain;
|
||||||
|
};
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "UsbmsgHandler.h"
|
||||||
|
#include "Scanner.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool read_regs(unsigned int *regs, int regindex, int creg, void* scanner)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write_regs(unsigned int *regs, int regindex, int creg, void* scanner)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
bool read_regs(unsigned int *regs, int regindex, int creg, void* scanner);
|
||||||
|
|
||||||
|
bool write_regs(unsigned int *regs, int regindex, int creg, void* scanner);
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include "ZouZhiMotor.h"
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
ZouZhiMotor::ZouZhiMotor()
|
||||||
|
: Motor(motorPorts_Zouzhi)
|
||||||
|
{
|
||||||
|
auto t_smbtype = smbtype == SMBType::MB_DRV_TMC216 ? MotorConfig::MTBDType::MT_TMC : MotorConfig::MTBDType::MT_DRV;
|
||||||
|
m_zouparamex = m_mtconfig->GetMotorSpeedParam(true, t_smbtype, 4, 1, 1);
|
||||||
|
speedConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
ZouZhiMotor::~ZouZhiMotor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZouZhiMotor::start()
|
||||||
|
{
|
||||||
|
Motor::setDirection(0);
|
||||||
|
Motor::start(delays, m_zouparamex.mt_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZouZhiMotor::speedChange(int speed, int dpi, int colormode) // speed should be in range [0,5] (by ply,at 2019.5.23)
|
||||||
|
{
|
||||||
|
auto t_smbtype = smbtype == SMBType::MB_DRV_TMC216 ? MotorConfig::MTBDType::MT_TMC : MotorConfig::MTBDType::MT_DRV;
|
||||||
|
m_zouparamex = m_mtconfig->GetMotorSpeedParam(true, t_smbtype, 4, colormode, dpi);
|
||||||
|
speedConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZouZhiMotor::speedRecover()
|
||||||
|
{
|
||||||
|
speedConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZouZhiMotor::speedConfig()
|
||||||
|
{
|
||||||
|
LOG("ZouZhiMotor speed=%d \n dpi=%d \n colormode=%d \n finalPeriod=%d \n Fmin=%d \n a=%.2f \n offset=%.2f \n stepnum=%.2f \n finalDelay=%.2f \n ",
|
||||||
|
m_zouparamex.speed,
|
||||||
|
m_zouparamex.dpi,
|
||||||
|
m_zouparamex.colormode,
|
||||||
|
m_zouparamex.mt_param.finalPeriod,
|
||||||
|
m_zouparamex.mt_param.Fmin,
|
||||||
|
m_zouparamex.mt_param.a,
|
||||||
|
m_zouparamex.mt_param.offset,
|
||||||
|
m_zouparamex.mt_param.stepnum,
|
||||||
|
m_zouparamex.mt_param.finalDelay);
|
||||||
|
|
||||||
|
delays.clear();
|
||||||
|
|
||||||
|
delays = speedup_cfg(m_zouparamex.mt_param.finalPeriod, m_zouparamex.mt_param.Fmin, m_zouparamex.mt_param.stepnum, m_zouparamex.mt_param.a,
|
||||||
|
m_zouparamex.mt_param.offset, m_zouparamex.mt_param.finalDelay);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Motor.h"
|
||||||
|
class ZouZhiMotor : public Motor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZouZhiMotor();
|
||||||
|
~ZouZhiMotor();
|
||||||
|
virtual void start();
|
||||||
|
void speedChange(int speed, int dpi = 1,int colormode = 1);
|
||||||
|
void speedRecover();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<int> delays;
|
||||||
|
MotorSpeedParamEx m_zouparamex;
|
||||||
|
void speedConfig();
|
||||||
|
};
|
|
@ -0,0 +1,70 @@
|
||||||
|
#pragma once
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
|
class AutoSemaphore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoSemaphore()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~AutoSemaphore()
|
||||||
|
{
|
||||||
|
notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void notify_all()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lck(mutx);
|
||||||
|
cv.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool wait(int timeout_ms)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(mutx);
|
||||||
|
return cv.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::no_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::mutex mutx;
|
||||||
|
std::condition_variable cv;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AutoEvent : public AutoSemaphore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoEvent()
|
||||||
|
: bNotify(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~AutoEvent()
|
||||||
|
{
|
||||||
|
notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void notify_all()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lck(mutx);
|
||||||
|
bNotify = true;
|
||||||
|
cv.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool wait(int timeout_ms)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(mutx);
|
||||||
|
if (bNotify)
|
||||||
|
{
|
||||||
|
bNotify = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = cv.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::no_timeout;
|
||||||
|
bNotify = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
volatile bool bNotify;
|
||||||
|
};
|
|
@ -0,0 +1,12 @@
|
||||||
|
//#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
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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 <cubex@foxmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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
|
|
@ -0,0 +1,113 @@
|
||||||
|
|
||||||
|
此修改说明适用于华高G300~G400系列扫描仪scanservice
|
||||||
|
|
||||||
|
2020年9月26日
|
||||||
|
G300/G400 scanservice更新日志
|
||||||
|
1.scanservice中增加进程ID唯一性判断,避免系统存在多个scanservice
|
||||||
|
2.USB升级增加更改update包权限更改
|
||||||
|
2020年10月17日
|
||||||
|
G300/G400 scanservice更新日志
|
||||||
|
1.增加平场校正完成通知功能;
|
||||||
|
2.增加平场校正参数配置功能;
|
||||||
|
3.增加USB控制重启功能;
|
||||||
|
4.增加横向纵向修正系数;
|
||||||
|
5.增加PC配置序列号功能;
|
||||||
|
2020年10月29日19:39:32
|
||||||
|
1.增加jpeg图像bulk传输分包传输,以避免出现传输失败;
|
||||||
|
2020年11月26日20:59:05
|
||||||
|
1.增加ADC reset功能
|
||||||
|
2.调整USB write bulk接口传输包大小,避免传输失败丢图问题;
|
||||||
|
2020年11月29日16:14:10(G300 UV)
|
||||||
|
1.UV机器修复socket 端口重用问题
|
||||||
|
2.开盖异常显示复位显示不正确问题
|
||||||
|
3.修复双张显示卡纸问题
|
||||||
|
2021年1月11日13:18:14
|
||||||
|
1.增加教育版与通用版本,针对两种模式校正算法调整;
|
||||||
|
2.调整校正算法 曝光最大为3300,对应FPGA版本也为3300
|
||||||
|
3.增加RSA固件校验
|
||||||
|
4.升级流程调整,固件下载下去先做校验,然后由PC发出指令进行重启;
|
||||||
|
5.优化main函数整合冗余代码(读写scaninfo文件)
|
||||||
|
2021年2月28日
|
||||||
|
修改说明:
|
||||||
|
1.增加scanservice控制休眠;
|
||||||
|
2.增加检测CIS类型代码;
|
||||||
|
3.增加休眠时间控制与终结休眠脚本;
|
||||||
|
4.增加USB休眠时间设置读取;
|
||||||
|
5.重构main函数部分代码
|
||||||
|
2021年3月5日
|
||||||
|
修改说明:
|
||||||
|
1.增加fpga固件升级功能,fpga升级包名称为fpgaupdatefile.bin。存放位置为/etc/fpgaupdatefile.bin;
|
||||||
|
2.系统固件需要升级为支持mtp的内核版本,否则将会导致升级失败;
|
||||||
|
3.修改cmakelists文件,增加解决mtp源码编译问题;
|
||||||
|
2021年3月29日
|
||||||
|
修改说明:
|
||||||
|
1.增加32字节buffer token设置 读取 存取功能
|
||||||
|
2.修改G400 70 ppm下 走纸电机 FMin频率,以解决电机扭矩偏小问题
|
||||||
|
2021年6月5日
|
||||||
|
1.修复程序退出时,报段错误问题;
|
||||||
|
2.增加低功耗唤醒协议,用于区分scanservice运行着或usbmonitor运行着,PC软件针对这两种模式做调整;
|
||||||
|
3.fpga升级方式调整,若需更新只需将文件拷贝至etc下即可;
|
||||||
|
4.增加尺寸检测功能,修复210418版本只能扫描一次,第二次启动异常问题;
|
||||||
|
5.修复CIS类型检测错误问题;
|
||||||
|
6.countdown.sh脚本低功耗控制调整;
|
||||||
|
7.G300 扫描增加60ppm
|
||||||
|
2021年10月20日
|
||||||
|
1.片上增加PC速度可配置功能;
|
||||||
|
2.增加USBVID PID可调整功能;
|
||||||
|
3.修复校正offset控制色条宽度不正确问题(导致条纹现象),432->288;
|
||||||
|
4.校正实时输出校正信息到PC功能;
|
||||||
|
2021-11-23
|
||||||
|
1.将明场目标值提高到200,暗场最大值提高到10,避免敦南cis无法校正通过;
|
||||||
|
2.校正扫描增益一致,校正查值表采用数字增益放大1.2倍;
|
||||||
|
2022-01-14
|
||||||
|
1.增加获取系统信息通信接口(sysinfo);
|
||||||
|
2.增加设置200 300 600 dpi 横纵修正系数,兼容以前协议;
|
||||||
|
3.重构部分代码;
|
||||||
|
4.明场均值降低至180,数字增益系数放大至1.42;
|
||||||
|
5.电机板版本 CIS类型增加自动识别接口;
|
||||||
|
6.由于板子自带内存2GB,600DPI会导致内存崩溃,现仅支持真实200 300DPI;
|
||||||
|
7.调整校正暗场校正算法,使用最低暗场值最低大于3,即满足暗场校过标准;
|
||||||
|
8.由于尺寸检测精度问题,本版本暂时屏蔽尺寸检测功能;
|
||||||
|
2022-01-15
|
||||||
|
1. 修复校正完成后位至校正标志位复位,导致上层取图报取图超时问题;
|
||||||
|
2. 修复300dpi 长纸不能走完问题;
|
||||||
|
3. 修复设置休眠时间后,扫描一张设置进入低功耗的时间不生效问题;
|
||||||
|
2022-01-17
|
||||||
|
1. 由于匹配原始尺寸采集存在误触发过纸信号情况,屏蔽掉自适应幅面功能;
|
||||||
|
2. 70ppm 速度提升至75ppm
|
||||||
|
2022年2月15日
|
||||||
|
1. 更新校正算法(支持文本模式和图片模式)
|
||||||
|
2. 变更扫描配置结构体成员,增加lutmode模式
|
||||||
|
3. 增加Scansysinfo信息输出接口
|
||||||
|
2022年3月21日
|
||||||
|
1. 重构电机版本自动识别以及cis识别,ICapturer和IMotor接口;
|
||||||
|
2. 开放增加电机板调速接口;
|
||||||
|
3. 增加main函数传参 启动校正功能;
|
||||||
|
4. 开放尺寸检测代码,更新尺寸检测代码;
|
||||||
|
5. 修复固件版本号更新延迟问题;
|
||||||
|
6. 校正未开线程,导致校正完成后pc端才能收到校正信息输出日志;
|
||||||
|
7. 电机参数增加sp关联项,设置速度模式时,更新调速sp至camerparams.json文件中;
|
||||||
|
8. 适配不同内存大小 300 600 dpi 扫描时配置fpga分辨率,2GB 配置600dpi 则按照300 dpi采集
|
||||||
|
9. 修复尺寸检测图像计数复位异常,导致PC取图超时(未上报stopscan)
|
||||||
|
2022年3月24日
|
||||||
|
1. 适配3288 300机器
|
||||||
|
2. 基于3月21日版本代码基础上丢弃以前扫描参数配置保存方式,目前300 400 按照统一的方式配置
|
||||||
|
2022年3月31日
|
||||||
|
1. 修复电机复位随机转动时间,避免搓纸轮磨损位置固定;
|
||||||
|
2. 修复尺寸检测double letter 以及 letter尺寸异常问题;
|
||||||
|
3. Monocapturer 类增加多线程进行处理
|
||||||
|
4. 更正double letter 尺寸(8.5inc * 22 inc),以及采集高度
|
||||||
|
5. 优化json存储,避免json对象key不存在时,导致程序崩溃问题;
|
||||||
|
2022年4月11日 pm
|
||||||
|
1. g300 电机复位部分不到位问题修复;
|
||||||
|
2. 优化校正部分 sp与曝光上限限制问题;
|
||||||
|
3. 修复Capturer类PC配置畸变校正参数不生效问题;
|
||||||
|
2022年4月20日
|
||||||
|
1. 修复长纸模式下,卡纸问题;
|
||||||
|
2. 增加搓纸电机减速过程;
|
||||||
|
2022年6月5日 蒋志强
|
||||||
|
1. d8版本尺寸检测问题修复
|
||||||
|
2022年11月6日 彭明
|
||||||
|
1. 针对G300 增加真实300DPI 模式;
|
||||||
|
2. 调整Capture 类,增加300DPI彩色灰度校正模式;
|
||||||
|
3. 调整300DPI 配置fpga 以及v4l2 高度配置;
|
|
@ -0,0 +1,402 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "correct_ultis.h"
|
||||||
|
#include "CImageMerge.h"
|
||||||
|
#define USE_NEWFLAT
|
||||||
|
//using namespace cv;
|
||||||
|
|
||||||
|
//设置一面的offset值
|
||||||
|
void setOffset(int *config, int step)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
int *offset = config + i;
|
||||||
|
*offset += step;
|
||||||
|
if (*offset < 0)
|
||||||
|
*offset = 1;
|
||||||
|
if (*offset > 255)
|
||||||
|
*offset = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cv::Mat extractRepresentRow2(const cv::Mat &src)
|
||||||
|
// {
|
||||||
|
// cv::Mat BWbalenceSrc(1, src.cols * src.channels(), CV_8UC1);
|
||||||
|
|
||||||
|
// cv::Mat temp_imageBW(src.rows, src.cols * src.channels(), CV_8UC1, src.data);
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < BWbalenceSrc.cols; i++)
|
||||||
|
// BWbalenceSrc.at<u_char>(0, i) = cv::mean(temp_imageBW(cv::Rect(i, 0, 1, temp_imageBW.rows)))[0];
|
||||||
|
|
||||||
|
// return BWbalenceSrc;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat loadLUT(const std::string &file)
|
||||||
|
// {
|
||||||
|
// cv::Mat dataFile = cv::imread(file, cv::IMREAD_ANYCOLOR);
|
||||||
|
// long total = dataFile.total();
|
||||||
|
// int step = total / 256;
|
||||||
|
|
||||||
|
// int channel = 1;
|
||||||
|
// #ifndef USE_NEWFLAT
|
||||||
|
// if (step == 4896 || step == 7344)
|
||||||
|
// channel = 408;
|
||||||
|
// else if (step == 14688 || step == 22032 || step == 44064)
|
||||||
|
// channel = 432; // 486
|
||||||
|
// #else
|
||||||
|
// #ifdef G400
|
||||||
|
// channel = 408;
|
||||||
|
// #else
|
||||||
|
// channel = 432;
|
||||||
|
// #endif
|
||||||
|
// #endif
|
||||||
|
// cv::Mat lut(step / channel, 256, CV_8UC(channel));
|
||||||
|
// memcpy(lut.data, dataFile.data, total);
|
||||||
|
// return lut;
|
||||||
|
// }
|
||||||
|
|
||||||
|
void initLut(const std::string lutpath, bool iscolor)
|
||||||
|
{
|
||||||
|
// if (!lutpath.empty() && (access(lutpath.c_str(), F_OK) == 0))
|
||||||
|
// {
|
||||||
|
// if (iscolor)
|
||||||
|
// {
|
||||||
|
// lutColorMat = loadLUT(lutpath); //彩色校正值
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// lutGrayMat = loadLUT(lutpath); //灰色校正值
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// void correctColor(cv::Mat &src, int dpi, int mode, bool lutgraghic)
|
||||||
|
// {
|
||||||
|
// Mat lutMat;
|
||||||
|
// #ifdef USE_NEWFLAT
|
||||||
|
// FPGAConfigParam param = GetFpgaparam(dpi, mode);
|
||||||
|
// std::string path = lutgraghic ? param.LutPath : param.TextLutPath;
|
||||||
|
// #else
|
||||||
|
// std::string path = param.LutPath;
|
||||||
|
// #endif
|
||||||
|
// if (src.type() == CV_8UC3)
|
||||||
|
// {
|
||||||
|
// if (lutColorMat.empty())
|
||||||
|
// {
|
||||||
|
// if (access(path.c_str(), F_OK) != -1)
|
||||||
|
// {
|
||||||
|
// lutColorMat = loadLUT(path);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// printf("error error error %s NOT FOUND \n", path.c_str());
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// lutMat = lutColorMat;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if (lutGrayMat.empty())
|
||||||
|
// {
|
||||||
|
// if (access(path.c_str(), F_OK) != -1)
|
||||||
|
// {
|
||||||
|
// lutGrayMat = loadLUT(path);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// printf("error error error %s NOT FOUND", path.c_str());
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// lutMat = lutGrayMat;
|
||||||
|
// }
|
||||||
|
// if (lutMat.empty())
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat image_temp(src.rows, src.cols * src.channels() / lutMat.channels(), CV_8UC(lutMat.channels()), src.data);
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < image_temp.cols; i++)
|
||||||
|
// cv::LUT(image_temp(cv::Rect(i, 0, 1, image_temp.rows)), lutMat(cv::Rect(0, i, 256, 1)), image_temp(cv::Rect(i, 0, 1, image_temp.rows)));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void creatLUTData(int dpi, int mode)
|
||||||
|
// {
|
||||||
|
// printf("eneter creatLUTData \n");
|
||||||
|
// FPGAConfigParam param = GetFpgaparam(dpi, mode);
|
||||||
|
// auto colormode = mode == 1 ? IMREAD_COLOR : IMREAD_GRAYSCALE;
|
||||||
|
// std::string blackPath = param.Flat_BwPath;
|
||||||
|
// std::string whitePath = param.Flat_WhitePath;
|
||||||
|
|
||||||
|
// cv::Mat lut;
|
||||||
|
// cv::Mat twMat = cv::imread(whitePath, colormode);
|
||||||
|
// cv::Mat tbMat = cv::imread(blackPath, colormode);
|
||||||
|
// cv::Mat wMat, bMat;
|
||||||
|
// if (mode == 1)
|
||||||
|
// {
|
||||||
|
// wMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, twMat.data);
|
||||||
|
// bMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, tbMat.data);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// wMat = twMat;
|
||||||
|
// bMat = tbMat;
|
||||||
|
// }
|
||||||
|
// #ifdef USE_NEWFLAT
|
||||||
|
// //lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat), false);
|
||||||
|
// //cv::imwrite(param.LutPath, lut);
|
||||||
|
|
||||||
|
// lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat), true);
|
||||||
|
// cv::imwrite(param.TextLutPath, lut);
|
||||||
|
// #else
|
||||||
|
// lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), dpi, mode);
|
||||||
|
// // Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1);
|
||||||
|
// // memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256);
|
||||||
|
// cv::imwrite(param.LutPath, lut);
|
||||||
|
// #endif
|
||||||
|
// printf("exit creatLUTData \n");
|
||||||
|
// }
|
||||||
|
|
||||||
|
FPGAConfigParam GetFpgaparam(int dpi, int mode)
|
||||||
|
{
|
||||||
|
//FPGAConfigParam param = CorrectParam().GetFpgaparam(dpi, mode);
|
||||||
|
return correctparam.GetFpgaparam(dpi, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveFpgaparam(FPGAConfigParam ¶m)
|
||||||
|
{
|
||||||
|
correctparam.SaveCorrectParam(param);
|
||||||
|
//CorrectParam().SaveCorrectParam(param);
|
||||||
|
}
|
||||||
|
// cv::Mat colMean(const cv::Mat &image)
|
||||||
|
// {
|
||||||
|
// cv::Mat meanMat(1, image.step, CV_8UC1);
|
||||||
|
// cv::Mat tempMat(image.rows, image.step, CV_8UC1, image.data);
|
||||||
|
// for (int i = 0; i < tempMat.step; i++)
|
||||||
|
// meanMat.data[i] = cv::mean(tempMat(cv::Rect(i, 0, 1, tempMat.rows)))[0];
|
||||||
|
|
||||||
|
// return meanMat;
|
||||||
|
// }
|
||||||
|
|
||||||
|
float gamma(float value, float ex)
|
||||||
|
{
|
||||||
|
return 0.0;//cv::pow(value / 255.0f, 1.0f / ex) * 255.0f + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GAMMA_EX 1.7f
|
||||||
|
#define BLACK_OFFSET 0
|
||||||
|
void fittingLUT(const std::vector<u_char> &points, u_char min_value, u_char max_value, u_char *data)
|
||||||
|
{
|
||||||
|
// float step = max_value - min_value + 1;
|
||||||
|
// memset(data, min_value, 127);
|
||||||
|
// memset(data + 127, max_value, 129);
|
||||||
|
// int b = points[0];
|
||||||
|
// int w = points[1];
|
||||||
|
// int tb = min_value;
|
||||||
|
// int tw = max_value;
|
||||||
|
|
||||||
|
// step = cv::max((float)(tw - tb + 1) / (float)(w - b + 1), 0.0f);
|
||||||
|
// float temp;
|
||||||
|
// for (int j = 0, length = (255 - b + 1); j < length; j++)
|
||||||
|
// {
|
||||||
|
// temp = gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET;
|
||||||
|
// data[j + b] = cv::min(255, cv::max(0, static_cast<int>(temp)));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::vector<double> caculate(const std::vector<double> &points_x, const std::vector<double> &points_y)
|
||||||
|
// {
|
||||||
|
// int MaxElement = points_x.size() - 1;
|
||||||
|
// //计算常数f
|
||||||
|
// double f = points_y[0];
|
||||||
|
// //求解
|
||||||
|
// int n, m;
|
||||||
|
// // double a[MaxElement][MaxElement+1];
|
||||||
|
// std::vector<std::vector<double>> a;
|
||||||
|
// // a.resize(MaxElement);
|
||||||
|
// for (int i = 0; i < MaxElement; i++)
|
||||||
|
// {
|
||||||
|
// std::vector<double> 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<double> result;
|
||||||
|
// for (int k = 0; k < n; k++)
|
||||||
|
// result.push_back(a[k][n]);
|
||||||
|
// result.push_back(f);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat createLUT(const std::vector<cv::Mat> &mats, bool isTextCorrect)
|
||||||
|
// {
|
||||||
|
// int rows = mats[0].cols;
|
||||||
|
// cv::Mat lut(rows, 256, CV_8UC1);
|
||||||
|
|
||||||
|
// double max_val, min_val;
|
||||||
|
// cv::minMaxIdx(mats[0], &min_val, nullptr);
|
||||||
|
// cv::minMaxIdx(mats[1], nullptr, &max_val);
|
||||||
|
// for (size_t i = 0; i < rows; i++)
|
||||||
|
// {
|
||||||
|
// std::vector<u_char> grayPoints;
|
||||||
|
// for (size_t j = 0; j < mats.size(); j++)
|
||||||
|
// grayPoints.push_back(mats[j].data[i]);
|
||||||
|
|
||||||
|
// fittingLUT(grayPoints, static_cast<u_char>(min_val), static_cast<u_char>(max_val), lut.data + i * 256);
|
||||||
|
// }
|
||||||
|
// if (isTextCorrect)
|
||||||
|
// {
|
||||||
|
// std::vector<double> points_x = {0, 25, 205, 255}, points_y = {0, 0, 230, 255};
|
||||||
|
// std::vector<double> coefficient = caculate(points_x, points_y);
|
||||||
|
|
||||||
|
// u_char buffer[256];
|
||||||
|
// for (int i = 0; i < 256; i++)
|
||||||
|
// {
|
||||||
|
// int temp = coefficient[0] * i * i * i + coefficient[1] * i * i + coefficient[2] * i + coefficient[3];
|
||||||
|
// buffer[i] = static_cast<u_char>(cv::min(255, cv::max(0, temp)));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat lut_lut(256, 1, CV_8UC1, buffer);
|
||||||
|
// cv::LUT(lut, lut_lut, lut);
|
||||||
|
// }
|
||||||
|
// return lut;
|
||||||
|
// }
|
||||||
|
#ifdef G400
|
||||||
|
#define CHANNEL 408
|
||||||
|
#else
|
||||||
|
#define CHANNEL 432
|
||||||
|
#endif
|
||||||
|
// cv::Mat calcLUT(const cv::Mat &black, const cv::Mat &white, bool isTextCorrection)
|
||||||
|
// {
|
||||||
|
// std::vector<cv::Mat> w;
|
||||||
|
// w.push_back(colMean(black));
|
||||||
|
// w.push_back(colMean(white));
|
||||||
|
// cv::Mat lut = createLUT(w, isTextCorrection);
|
||||||
|
|
||||||
|
// for (size_t i = 0, block = lut.rows / CHANNEL; i < block; i++)
|
||||||
|
// {
|
||||||
|
// cv::Mat lutROI = lut(cv::Rect(0, i * CHANNEL, 256, CHANNEL));
|
||||||
|
// cv::Mat tran;
|
||||||
|
// cv::transpose(lutROI, tran);
|
||||||
|
// memcpy(lutROI.data, tran.data, tran.total());
|
||||||
|
// }
|
||||||
|
// return lut;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, int dpi, bool colormode)
|
||||||
|
// {
|
||||||
|
// #ifndef USE_NEWFLAT
|
||||||
|
// if (black.empty() || white.empty() || black.channels() != 1 || white.channels() != 1 || black.step != white.step)
|
||||||
|
// return cv::Mat();
|
||||||
|
|
||||||
|
// int channel = 1;
|
||||||
|
// if (black.step == 4896 || black.step == 7344)
|
||||||
|
// channel = 408;
|
||||||
|
// else if (black.step == 14688 || black.step == 22032 || black.step == 44064)
|
||||||
|
// channel = 432; // 486
|
||||||
|
|
||||||
|
// if (channel == 1)
|
||||||
|
// return cv::Mat();
|
||||||
|
|
||||||
|
// const int rows = black.cols / channel;
|
||||||
|
// const int cols = 256;
|
||||||
|
// auto cc = CV_8UC(channel);
|
||||||
|
// Mat lut(rows, cols, CV_8UC(channel));
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < rows; i++)
|
||||||
|
// {
|
||||||
|
// Mat lut_row = lut(cv::Rect(0, i, cols, 1));
|
||||||
|
// unsigned char *ptr_buffer = lut_row.data;
|
||||||
|
// unsigned char *ptr_black = black.data + i * channel;
|
||||||
|
// unsigned char *ptr_white = white.data + i * channel;
|
||||||
|
// for (size_t j = 0; j < cols; j++)
|
||||||
|
// for (size_t k = 0; k < channel; k++)
|
||||||
|
// {
|
||||||
|
// if (ptr_black[k] >= ptr_white[k])
|
||||||
|
// {
|
||||||
|
// ptr_buffer[j * channel + k] = 0;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (j <= ptr_black[k])
|
||||||
|
// ptr_buffer[j * channel + k] = 0;
|
||||||
|
// else if (j >= ptr_white[k])
|
||||||
|
// ptr_buffer[j * channel + k] = 255;
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// float val = 255.0f * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]) * 1.275; //
|
||||||
|
// ptr_buffer[j * channel + k] = (unsigned char)cv::max(0.0f, cv::min(val, 255.0f));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// cv::Mat saveMat(black.step, 256, CV_8UC1, lut.data);
|
||||||
|
// return saveMat.clone();
|
||||||
|
// #else
|
||||||
|
// return calcLUT(black, white, false);
|
||||||
|
// #endif
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cv::Mat GetMergeMat(int dstwidth, int dstheight, int type, cv::Mat &mat)
|
||||||
|
// {
|
||||||
|
// return CImageMerge().MergeImage(type == CV_8UC3, mat, dstwidth, dstheight);
|
||||||
|
// }
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
#include <sstream>
|
||||||
|
//#include <opencv2/opencv.hpp>
|
||||||
|
#include "CameraParam.h"
|
||||||
|
#include "CorrectParam.h"
|
||||||
|
#include "CImageMerge.h"
|
||||||
|
|
||||||
|
|
||||||
|
//static cv::Mat lutGrayMat; //灰色校正值
|
||||||
|
//static cv::Mat lutColorMat; //彩色校正值
|
||||||
|
static CorrectParam correctparam;
|
||||||
|
|
||||||
|
void initStep();
|
||||||
|
|
||||||
|
void setOffset(int *config, int step);
|
||||||
|
|
||||||
|
//cv::Mat calcLUT(const cv::Mat& black, const cv::Mat& white, bool isTextCorrection);
|
||||||
|
|
||||||
|
//cv::Mat extractRepresentRow2(const cv::Mat& src);
|
||||||
|
|
||||||
|
void initLut(const std::string lutpath,bool iscolor);
|
||||||
|
|
||||||
|
//void correctColor(cv::Mat& src, int dpi,int mode,bool isTextCorrect=true);
|
||||||
|
|
||||||
|
void creatLUTData(int dpi , int mode);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
//cv::Mat GetMergeMat(int dstwidth ,int dstheight,int type,cv::Mat& mat);
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# A countdown timer
|
||||||
|
# GNU GPLv3
|
||||||
|
value_num=$#
|
||||||
|
HOU=$2
|
||||||
|
MIN=$3
|
||||||
|
SEC=$4
|
||||||
|
start(){
|
||||||
|
# If there are 3 arguments given, they become H, M, and S. Otherwise, the user is asked
|
||||||
|
if [ $HOU -eq 0 ] && [ $MIN -eq 0 ] && [ $SEC -eq 0 ] ; then
|
||||||
|
HOU=0
|
||||||
|
MIN=30
|
||||||
|
SEC=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SEC -lt 60 ] ; then
|
||||||
|
SEC=60
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Convert input to seconds
|
||||||
|
TIMER=$(( ($HOU*3600) + ($MIN*60) + $SEC ))
|
||||||
|
|
||||||
|
# Count down and output remaining time to temp file
|
||||||
|
while [ $TIMER -gt 0 ]
|
||||||
|
do
|
||||||
|
#printf "%02dh:%02dm:%02ds\n" $((TIMER/3600)) $((TIMER%3600/60)) $((TIMER%60))
|
||||||
|
printf "%02d:%02d:%02d\n" $((TIMER/3600)) $((TIMER%3600/60)) $((TIMER%60))
|
||||||
|
sleep 10
|
||||||
|
TIMER=$(( TIMER - 10 ))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $SEC -gt 0 ] ; then
|
||||||
|
#echo freeze > /sys/power/state
|
||||||
|
echo sleep > /etc/kernel_state
|
||||||
|
pkill scanservice
|
||||||
|
/etc/usbmonitor &
|
||||||
|
/etc/pm_control off
|
||||||
|
echo 0 > /sys/class/leds/red/brightness
|
||||||
|
echo 0 > /sys/class/leds/white/brightness
|
||||||
|
echo 0 > /sys/class/leds/green/brightness
|
||||||
|
echo 1 > /sys/class/leds/green/brightness
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
stop(){
|
||||||
|
echo "timer need to be killed"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$1" != "" ]; then
|
||||||
|
case $1 in
|
||||||
|
start|stop) "$1" ;;
|
||||||
|
esac
|
||||||
|
fi
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* @Author: Zhaozhonmin 1656963645@qq.com
|
||||||
|
* @Date: 2022-06-24 17:48:35
|
||||||
|
* @LastEditors: Zhaozhonmin 1656963645@qq.com
|
||||||
|
* @LastEditTime: 2023-02-06 19:04:54
|
||||||
|
* @FilePath: \zynq_ps\usb\inc\default_cfg.h
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* 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 <cubex@foxmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 512
|
||||||
|
|
||||||
|
#define USB_DEV_VENDOR_ID 0x3072 //0x04B4 // Linux Foundation
|
||||||
|
#define USB_DEV_PRODUCT_ID 0x0300 // PTP Gadget
|
||||||
|
|
||||||
|
#define USB_DEV_CLASS 0xFF // Still Imaging device
|
||||||
|
#define USB_DEV_SUBCLASS 0x1 //
|
||||||
|
#define USB_DEV_PROTOCOL 0x1 //
|
||||||
|
|
||||||
|
#define USB_DEV_VERSION 0x3008
|
||||||
|
|
||||||
|
#define USB_FFS_MODE 1
|
||||||
|
#define USB_FFS_AIO_MODE 2
|
||||||
|
|
||||||
|
#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 "HOLDTECS Technologies"
|
||||||
|
#define PRODUCT "HOLDTECS"
|
||||||
|
#define SERIALNUMBER "01234567ABCDEFG"
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,158 @@
|
||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
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 append_log(std::string log, bool printTime = true)
|
||||||
|
{
|
||||||
|
std::ofstream ofs(mPath, std::ios::app);
|
||||||
|
if (printTime)
|
||||||
|
{
|
||||||
|
// time_t now = time(0);
|
||||||
|
|
||||||
|
// struct timeb stTimeb;
|
||||||
|
|
||||||
|
// ftime(&stTimeb);
|
||||||
|
// 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);
|
||||||
|
struct tm *ptm;
|
||||||
|
struct timeb stTimeb;
|
||||||
|
static char loc_date[30];
|
||||||
|
|
||||||
|
ftime(&stTimeb);
|
||||||
|
ptm = localtime(&stTimeb.time);
|
||||||
|
sprintf(loc_date, "%02d-%02d %02d:%02d:%02d.%03d",
|
||||||
|
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, stTimeb.millitm);
|
||||||
|
ofs << loc_date << ": " << log << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ofs << " " << log << std::endl;
|
||||||
|
}
|
||||||
|
ofs.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::fstream fout(mPath, std::ios::out | std::ios::trunc);
|
||||||
|
fout.close();
|
||||||
|
}
|
||||||
|
catch (std::exception &e)
|
||||||
|
{
|
||||||
|
//LOG("error happened: %s \n", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
|
||||||
|
ss << buffer << ":" << ms.count();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
|
||||||
|
cs = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()) % 1000000;
|
||||||
|
ss << buffer << ":" << ms.count() << ":" << cs.count() % 1000;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
|
||||||
|
cs = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()) % 1000000;
|
||||||
|
ns = std::chrono::duration_cast<std::chrono::nanoseconds>(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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StopWatch()
|
||||||
|
{
|
||||||
|
_start = std::chrono::steady_clock::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
_start = std::chrono::steady_clock::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
double elapsed_s()
|
||||||
|
{
|
||||||
|
return std::chrono::duration<double>(std::chrono::steady_clock::now() - _start).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
double elapsed_ms()
|
||||||
|
{
|
||||||
|
return std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - _start).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
double elapsed_us()
|
||||||
|
{
|
||||||
|
return std::chrono::duration<double, std::micro>(std::chrono::steady_clock::now() - _start).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
double elapsed_ns()
|
||||||
|
{
|
||||||
|
return std::chrono::duration<double, std::nano>(std::chrono::steady_clock::now() - _start).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::chrono::steady_clock::time_point _start;
|
||||||
|
};
|
|
@ -0,0 +1,20 @@
|
||||||
|
project(fpgaupdate)
|
||||||
|
add_compile_options(-std=c++14)
|
||||||
|
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -O2")
|
||||||
|
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -O2")
|
||||||
|
aux_source_directory(${PROJECT_SOURCE_DIR} DIR_SRCS)
|
||||||
|
file(GLOB DIR_HEADS "${PROJECT_SOURCE_DIR}/*.h" "${PROJECT_SOURCE_DIR}/*.hpp")
|
||||||
|
set(DIR_SRCS ${DIR_SRCS} ${DIR_HEADS})
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME} STATIC ${DIR_SRCS})
|
||||||
|
|
||||||
|
# target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}
|
||||||
|
# ${PROJECT_SOURCE_DIR}/../3rdparty/nick
|
||||||
|
# ${PROJECT_SOURCE_DIR}/../ImageProcess
|
||||||
|
# ${PROJECT_SOURCE_DIR}/../3rdparty/opencv/include
|
||||||
|
# ${PROJECT_SOURCE_DIR}/../3rdparty/tiff/include
|
||||||
|
# ${PROJECT_SOURCE_DIR}/../../../sdk/include
|
||||||
|
# ${PROJECT_SOURCE_DIR}/../wrapper
|
||||||
|
# )
|
||||||
|
|
||||||
|
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
|
|
@ -0,0 +1,122 @@
|
||||||
|
#include "fpgacontrol.h"
|
||||||
|
#include "libmtd.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#define MTD_NODE "/dev/mtd0"
|
||||||
|
#define FPGAFILEPATH "/etc/fpgaupdatefile.bin"
|
||||||
|
|
||||||
|
fpgacontrol::fpgacontrol() :
|
||||||
|
m_fpgafile_fd(0),
|
||||||
|
m_updateEnable(false)
|
||||||
|
{
|
||||||
|
//printf("fpga version : %d \n", fpgaversion);
|
||||||
|
}
|
||||||
|
|
||||||
|
fpgacontrol::~fpgacontrol()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fpgacontrol::ifneedupdatefpga()
|
||||||
|
{
|
||||||
|
if ((access(FPGAFILEPATH, F_OK)) != -1)
|
||||||
|
{
|
||||||
|
m_updateEnable = true;
|
||||||
|
printf("found %s file ,will update fpga later!\n", FPGAFILEPATH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_updateEnable = false;
|
||||||
|
printf("%s file do not exist!\n", FPGAFILEPATH);
|
||||||
|
}
|
||||||
|
return m_updateEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fpgacontrol::updatefpga()
|
||||||
|
{
|
||||||
|
if (!m_updateEnable)
|
||||||
|
{
|
||||||
|
printf("checked don't need to update fpga\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return updatefpgafirmware(FPGAFILEPATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fpgacontrol::updatefpgafirmware(std::string fpgafirmpath)
|
||||||
|
{
|
||||||
|
system("echo 68 > /sys/class/gpio/export");
|
||||||
|
system("echo out > /sys/class/gpio/gpio68/direction");
|
||||||
|
system("echo 0 > /sys/class/gpio/gpio68/value");
|
||||||
|
if ((m_fpgafile_fd = open(MTD_NODE, O_RDWR)) <= 0)
|
||||||
|
{
|
||||||
|
printf("update fpga error,on open mtd node!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
libmtd_t desc;
|
||||||
|
desc = libmtd_open();
|
||||||
|
if (NULL == desc)
|
||||||
|
{
|
||||||
|
printf("libmtd_open error...\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mtd_dev_info dev_info;
|
||||||
|
mtd_get_dev_info(desc, MTD_NODE, &dev_info);
|
||||||
|
printf("mtd_num = %x\n", dev_info.mtd_num);
|
||||||
|
printf("major = %x\n", dev_info.major);
|
||||||
|
printf("minor = %x\n", dev_info.minor);
|
||||||
|
printf("type_str = %s\n", dev_info.type_str);
|
||||||
|
printf("name = %s\n", dev_info.name);
|
||||||
|
printf("size = %d\n", dev_info.size);
|
||||||
|
printf("eb_cnt = %d\n", dev_info.eb_cnt);
|
||||||
|
printf("eb_size = %d\n", dev_info.eb_size);
|
||||||
|
printf("min_io_size = %d\n", dev_info.min_io_size);
|
||||||
|
printf("subpage_size = %d\n", dev_info.subpage_size);
|
||||||
|
printf("oob_size = %d\n", dev_info.oob_size);
|
||||||
|
printf("region_cnt = %d\n", dev_info.region_cnt);
|
||||||
|
printf("writable = %d\n", dev_info.writable);
|
||||||
|
printf("bb_allowed = %d\n", dev_info.bb_allowed);
|
||||||
|
for (int i = 0; i < dev_info.eb_cnt; i++)
|
||||||
|
{
|
||||||
|
if (mtd_erase(desc, &dev_info, m_fpgafile_fd, i) != 0)
|
||||||
|
{
|
||||||
|
printf("mtd_erase error...........\n");
|
||||||
|
if (desc)
|
||||||
|
{
|
||||||
|
libmtd_close(desc);
|
||||||
|
desc = NULL;
|
||||||
|
}
|
||||||
|
if (m_fpgafile_fd)
|
||||||
|
{
|
||||||
|
close(m_fpgafile_fd);
|
||||||
|
m_fpgafile_fd = NULL;
|
||||||
|
}
|
||||||
|
//system("echo 1 > /sys/class/gpio/gpio221/value");
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = mtd_write_img(&dev_info, m_fpgafile_fd, 0, 0, fpgafirmpath.c_str());
|
||||||
|
libmtd_close(desc);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
printf("mtd_write_img failed...........\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("mtd_write_img success...........\n");
|
||||||
|
std::string rmcmd = "rm -f /etc/fpgaupdatefile.bin";
|
||||||
|
system(rmcmd.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class FpgaComm;
|
||||||
|
|
||||||
|
class fpgacontrol
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
public:
|
||||||
|
fpgacontrol();
|
||||||
|
~fpgacontrol();
|
||||||
|
bool ifneedupdatefpga();
|
||||||
|
bool updatefpga();
|
||||||
|
private:
|
||||||
|
bool updatefpgafirmware(std::string fpgafirmpath);
|
||||||
|
private:
|
||||||
|
int m_fpgaversion;
|
||||||
|
int m_fpgafile_fd;
|
||||||
|
bool m_updateEnable;
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,357 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008, 2009 Nokia Corporation
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Author: Artem Bityutskiy
|
||||||
|
*
|
||||||
|
* MTD library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Imported from mtd-utils by dehrenberg */
|
||||||
|
|
||||||
|
#ifndef __LIBMTD_H__
|
||||||
|
#define __LIBMTD_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Needed for uint8_t, uint64_t
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Maximum MTD device name length */
|
||||||
|
#define MTD_NAME_MAX 127
|
||||||
|
/* Maximum MTD device type string length */
|
||||||
|
#define MTD_TYPE_MAX 64
|
||||||
|
|
||||||
|
/* MTD library descriptor */
|
||||||
|
typedef void * libmtd_t;
|
||||||
|
|
||||||
|
/* Forward decls */
|
||||||
|
struct region_info_user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @mtd_dev_cnt: count of MTD devices in system
|
||||||
|
* @lowest_mtd_num: lowest MTD device number in system
|
||||||
|
* @highest_mtd_num: highest MTD device number in system
|
||||||
|
* @sysfs_supported: non-zero if sysfs is supported by MTD
|
||||||
|
*/
|
||||||
|
struct mtd_info
|
||||||
|
{
|
||||||
|
int mtd_dev_cnt;
|
||||||
|
int lowest_mtd_num;
|
||||||
|
int highest_mtd_num;
|
||||||
|
unsigned int sysfs_supported:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mtd_dev_info - information about an MTD device.
|
||||||
|
* @mtd_num: MTD device number
|
||||||
|
* @major: major number of corresponding character device
|
||||||
|
* @minor: minor number of corresponding character device
|
||||||
|
* @type: flash type (constants like %MTD_NANDFLASH defined in mtd-abi.h)
|
||||||
|
* @type_str: static R/O flash type string
|
||||||
|
* @name: device name
|
||||||
|
* @size: device size in bytes
|
||||||
|
* @eb_cnt: count of eraseblocks
|
||||||
|
* @eb_size: eraseblock size
|
||||||
|
* @min_io_size: minimum input/output unit size
|
||||||
|
* @subpage_size: sub-page size
|
||||||
|
* @oob_size: OOB size (zero if the device does not have OOB area)
|
||||||
|
* @region_cnt: count of additional erase regions
|
||||||
|
* @writable: zero if the device is read-only
|
||||||
|
* @bb_allowed: non-zero if the MTD device may have bad eraseblocks
|
||||||
|
*/
|
||||||
|
struct mtd_dev_info
|
||||||
|
{
|
||||||
|
int mtd_num;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
int type;
|
||||||
|
char type_str[MTD_TYPE_MAX + 1];
|
||||||
|
char name[MTD_NAME_MAX + 1];
|
||||||
|
long long size;
|
||||||
|
int eb_cnt;
|
||||||
|
int eb_size;
|
||||||
|
int min_io_size;
|
||||||
|
int subpage_size;
|
||||||
|
int oob_size;
|
||||||
|
int region_cnt;
|
||||||
|
unsigned int writable:1;
|
||||||
|
unsigned int bb_allowed:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* libmtd_open - open MTD library.
|
||||||
|
*
|
||||||
|
* This function initializes and opens the MTD library and returns MTD library
|
||||||
|
* descriptor in case of success and %NULL in case of failure. In case of
|
||||||
|
* failure, errno contains zero if MTD is not present in the system, or
|
||||||
|
* contains the error code if a real error happened.
|
||||||
|
*/
|
||||||
|
libmtd_t libmtd_open(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* libmtd_close - close MTD library.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
*/
|
||||||
|
void libmtd_close(libmtd_t desc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_dev_present - check whether a MTD device is present.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @mtd_num: MTD device number to check
|
||||||
|
*
|
||||||
|
* This function returns %1 if MTD device is present and %0 if not.
|
||||||
|
*/
|
||||||
|
int mtd_dev_present(libmtd_t desc, int mtd_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_get_info - get general MTD information.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @info: the MTD device information is returned here
|
||||||
|
*
|
||||||
|
* This function fills the passed @info object with general MTD information and
|
||||||
|
* returns %0 in case of success and %-1 in case of failure. If MTD subsystem is
|
||||||
|
* not present in the system, errno is set to @ENODEV.
|
||||||
|
*/
|
||||||
|
int mtd_get_info(libmtd_t desc, struct mtd_info *info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_get_dev_info - get information about an MTD device.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @node: name of the MTD device node
|
||||||
|
* @mtd: the MTD device information is returned here
|
||||||
|
*
|
||||||
|
* This function gets information about MTD device defined by the @node device
|
||||||
|
* node file and saves this information in the @mtd object. Returns %0 in case
|
||||||
|
* of success and %-1 in case of failure. If MTD subsystem is not present in the
|
||||||
|
* system, or the MTD device does not exist, errno is set to @ENODEV.
|
||||||
|
*/
|
||||||
|
int mtd_get_dev_info(libmtd_t desc, const char *node, struct mtd_dev_info *mtd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_get_dev_info1 - get information about an MTD device.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @mtd_num: MTD device number to fetch information about
|
||||||
|
* @mtd: the MTD device information is returned here
|
||||||
|
*
|
||||||
|
* This function is identical to 'mtd_get_dev_info()' except that it accepts
|
||||||
|
* MTD device number, not MTD character device.
|
||||||
|
*/
|
||||||
|
int mtd_get_dev_info1(libmtd_t desc, int mtd_num, struct mtd_dev_info *mtd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_lock - lock eraseblocks.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to lock
|
||||||
|
*
|
||||||
|
* This function locks eraseblock @eb. Returns %0 in case of success and %-1
|
||||||
|
* in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_lock(const struct mtd_dev_info *mtd, int fd, int eb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_unlock - unlock eraseblocks.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to lock
|
||||||
|
*
|
||||||
|
* This function unlocks eraseblock @eb. Returns %0 in case of success and %-1
|
||||||
|
* in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_unlock(const struct mtd_dev_info *mtd, int fd, int eb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_erase - erase an eraseblock.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to erase
|
||||||
|
*
|
||||||
|
* This function erases eraseblock @eb of MTD device described by @fd. Returns
|
||||||
|
* %0 in case of success and %-1 in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_erase(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_regioninfo - get information about an erase region.
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @regidx: index of region to look up
|
||||||
|
* @reginfo: the region information is returned here
|
||||||
|
*
|
||||||
|
* This function gets information about an erase region defined by the
|
||||||
|
* @regidx index and saves this information in the @reginfo object.
|
||||||
|
* Returns %0 in case of success and %-1 in case of failure. If the
|
||||||
|
* @regidx is not valid or unavailable, errno is set to @ENODEV.
|
||||||
|
*/
|
||||||
|
int mtd_regioninfo(int fd, int regidx, struct region_info_user *reginfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_is_locked - see if the specified eraseblock is locked.
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to check
|
||||||
|
*
|
||||||
|
* This function checks to see if eraseblock @eb of MTD device described
|
||||||
|
* by @fd is locked. Returns %0 if it is unlocked, %1 if it is locked, and
|
||||||
|
* %-1 in case of failure. If the ioctl is not supported (support was added in
|
||||||
|
* Linux kernel 2.6.36) or this particular device does not support it, errno is
|
||||||
|
* set to @ENOTSUPP.
|
||||||
|
*/
|
||||||
|
int mtd_is_locked(const struct mtd_dev_info *mtd, int fd, int eb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_torture - torture an eraseblock.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to torture
|
||||||
|
*
|
||||||
|
* This function tortures eraseblock @eb. Returns %0 in case of success and %-1
|
||||||
|
* in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_torture(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_is_bad - check if eraseblock is bad.
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to check
|
||||||
|
*
|
||||||
|
* This function checks if eraseblock @eb is bad. Returns %0 if not, %1 if yes,
|
||||||
|
* and %-1 in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_is_bad(const struct mtd_dev_info *mtd, int fd, int eb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_mark_bad - mark an eraseblock as bad.
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to mark as bad
|
||||||
|
*
|
||||||
|
* This function marks eraseblock @eb as bad. Returns %0 in case of success and
|
||||||
|
* %-1 in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_mark_bad(const struct mtd_dev_info *mtd, int fd, int eb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_read - read data from an MTD device.
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to read from
|
||||||
|
* @offs: offset withing the eraseblock to read from
|
||||||
|
* @buf: buffer to read data to
|
||||||
|
* @len: how many bytes to read
|
||||||
|
*
|
||||||
|
* This function reads @len bytes of data from eraseblock @eb and offset @offs
|
||||||
|
* of the MTD device defined by @mtd and stores the read data at buffer @buf.
|
||||||
|
* Returns %0 in case of success and %-1 in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
|
||||||
|
void *buf, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_write - write data to an MTD device.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to write to
|
||||||
|
* @offs: offset withing the eraseblock to write to
|
||||||
|
* @data: data buffer to write
|
||||||
|
* @len: how many data bytes to write
|
||||||
|
* @oob: OOB buffer to write
|
||||||
|
* @ooblen: how many OOB bytes to write
|
||||||
|
* @mode: write mode (e.g., %MTD_OOB_PLACE, %MTD_OOB_RAW)
|
||||||
|
*
|
||||||
|
* This function writes @len bytes of data to eraseblock @eb and offset @offs
|
||||||
|
* of the MTD device defined by @mtd. Returns %0 in case of success and %-1 in
|
||||||
|
* case of failure.
|
||||||
|
*
|
||||||
|
* Can only write to a single page at a time if writing to OOB.
|
||||||
|
*/
|
||||||
|
int mtd_write(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb,
|
||||||
|
int offs, void *data, int len, void *oob, int ooblen,
|
||||||
|
uint8_t mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_read_oob - read out-of-band area.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @start: page-aligned start address
|
||||||
|
* @length: number of OOB bytes to read
|
||||||
|
* @data: read buffer
|
||||||
|
*
|
||||||
|
* This function reads @length OOB bytes starting from address @start on
|
||||||
|
* MTD device described by @fd. The address is specified as page byte offset
|
||||||
|
* from the beginning of the MTD device. This function returns %0 in case of
|
||||||
|
* success and %-1 in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_read_oob(libmtd_t desc, const struct mtd_dev_info *mtd, int fd,
|
||||||
|
uint64_t start, uint64_t length, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_write_oob - write out-of-band area.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @start: page-aligned start address
|
||||||
|
* @length: number of OOB bytes to write
|
||||||
|
* @data: write buffer
|
||||||
|
*
|
||||||
|
* This function writes @length OOB bytes starting from address @start on
|
||||||
|
* MTD device described by @fd. The address is specified as page byte offset
|
||||||
|
* from the beginning of the MTD device. Returns %0 in case of success and %-1
|
||||||
|
* in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_write_oob(libmtd_t desc, const struct mtd_dev_info *mtd, int fd,
|
||||||
|
uint64_t start, uint64_t length, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_write_img - write a file to MTD device.
|
||||||
|
* @mtd: MTD device description object
|
||||||
|
* @fd: MTD device node file descriptor
|
||||||
|
* @eb: eraseblock to write to
|
||||||
|
* @offs: offset withing the eraseblock to write to
|
||||||
|
* @img_name: the file to write
|
||||||
|
*
|
||||||
|
* This function writes an image @img_name the MTD device defined by @mtd. @eb
|
||||||
|
* and @offs are the starting eraseblock and offset on the MTD device. Returns
|
||||||
|
* %0 in case of success and %-1 in case of failure.
|
||||||
|
*/
|
||||||
|
int mtd_write_img(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
|
||||||
|
const char *img_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtd_probe_node - test MTD node.
|
||||||
|
* @desc: MTD library descriptor
|
||||||
|
* @node: the node to test
|
||||||
|
*
|
||||||
|
* This function tests whether @node is an MTD device node and returns %1 if it
|
||||||
|
* is, and %-1 if it is not (errno is %ENODEV in this case) or if an error
|
||||||
|
* occurred.
|
||||||
|
*/
|
||||||
|
int mtd_probe_node(libmtd_t desc, const char *node);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LIBMTD_H__ */
|
|
@ -0,0 +1,224 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Artem Bityutskiy, 2007, 2008
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Imported from mtd-utils by dehrenberg */
|
||||||
|
|
||||||
|
#ifndef __MTD_UTILS_COMMON_H__
|
||||||
|
#define __MTD_UTILS_COMMON_H__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <features.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
|
#ifndef PROGRAM_NAME
|
||||||
|
# error "You must define PROGRAM_NAME before including this header"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MIN /* some C lib headers define this for us */
|
||||||
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
#ifndef MAX
|
||||||
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
#define min(a, b) MIN(a, b) /* glue for linux kernel source */
|
||||||
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||||
|
|
||||||
|
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
|
||||||
|
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
|
||||||
|
|
||||||
|
#define min_t(t,x,y) ({ \
|
||||||
|
typeof((x)) _x = (x); \
|
||||||
|
typeof((y)) _y = (y); \
|
||||||
|
(_x < _y) ? _x : _y; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define max_t(t,x,y) ({ \
|
||||||
|
typeof((x)) _x = (x); \
|
||||||
|
typeof((y)) _y = (y); \
|
||||||
|
(_x > _y) ? _x : _y; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#ifndef O_CLOEXEC
|
||||||
|
#define O_CLOEXEC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* define a print format specifier for off_t */
|
||||||
|
#ifdef __USE_FILE_OFFSET64
|
||||||
|
#define PRIxoff_t PRIx64
|
||||||
|
#define PRIdoff_t PRId64
|
||||||
|
#else
|
||||||
|
#define PRIxoff_t "l" PRIx32
|
||||||
|
#define PRIdoff_t "l" PRId32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Verbose messages */
|
||||||
|
#define bareverbose(verbose, fmt, ...) do { \
|
||||||
|
if (verbose) \
|
||||||
|
printf(fmt, ##__VA_ARGS__); \
|
||||||
|
} while(0)
|
||||||
|
#define verbose(verbose, fmt, ...) \
|
||||||
|
bareverbose(verbose, "%s: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/* Normal messages */
|
||||||
|
#define normsg_cont(fmt, ...) do { \
|
||||||
|
printf("%s: " fmt, PROGRAM_NAME, ##__VA_ARGS__); \
|
||||||
|
} while(0)
|
||||||
|
#define normsg(fmt, ...) do { \
|
||||||
|
normsg_cont(fmt "\n", ##__VA_ARGS__); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* Error messages */
|
||||||
|
#define errmsg(fmt, ...) ({ \
|
||||||
|
fprintf(stderr, "%s: error!: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__); \
|
||||||
|
-1; \
|
||||||
|
})
|
||||||
|
#define errmsg_die(fmt, ...) do { \
|
||||||
|
exit(errmsg(fmt, ##__VA_ARGS__)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* System error messages */
|
||||||
|
#define sys_errmsg(fmt, ...) ({ \
|
||||||
|
int _err = errno; \
|
||||||
|
errmsg(fmt, ##__VA_ARGS__); \
|
||||||
|
fprintf(stderr, "%*serror %d (%s)\n", (int)sizeof(PROGRAM_NAME) + 1,\
|
||||||
|
"", _err, strerror(_err)); \
|
||||||
|
-1; \
|
||||||
|
})
|
||||||
|
#define sys_errmsg_die(fmt, ...) do { \
|
||||||
|
exit(sys_errmsg(fmt, ##__VA_ARGS__)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* Warnings */
|
||||||
|
#define warnmsg(fmt, ...) do { \
|
||||||
|
fprintf(stderr, "%s: warning!: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#if defined(__UCLIBC__)
|
||||||
|
/* uClibc versions before 0.9.34 don't have rpmatch() */
|
||||||
|
#if __UCLIBC_MAJOR__ == 0 && \
|
||||||
|
(__UCLIBC_MINOR__ < 9 || \
|
||||||
|
(__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 34))
|
||||||
|
#undef rpmatch
|
||||||
|
#define rpmatch __rpmatch
|
||||||
|
static inline int __rpmatch(const char *resp)
|
||||||
|
{
|
||||||
|
return (resp[0] == 'y' || resp[0] == 'Y') ? 1 :
|
||||||
|
(resp[0] == 'n' || resp[0] == 'N') ? 0 : -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* prompt the user for confirmation
|
||||||
|
*/
|
||||||
|
static inline bool prompt(const char *msg, bool def)
|
||||||
|
{
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len;
|
||||||
|
bool ret = def;
|
||||||
|
|
||||||
|
do {
|
||||||
|
normsg_cont("%s (%c/%c) ", msg, def ? 'Y' : 'y', def ? 'n' : 'N');
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
while (getline(&line, &len, stdin) == -1) {
|
||||||
|
printf("failed to read prompt; assuming '%s'\n",
|
||||||
|
def ? "yes" : "no");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp("\n", line) != 0) {
|
||||||
|
switch (rpmatch(line)) {
|
||||||
|
case 0: ret = false; break;
|
||||||
|
case 1: ret = true; break;
|
||||||
|
case -1:
|
||||||
|
puts("unknown response; please try again");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
free(line);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int is_power_of_2(unsigned long long n)
|
||||||
|
{
|
||||||
|
return (n != 0 && ((n & (n - 1)) == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* simple_strtoX - convert a hex/dec/oct string into a number
|
||||||
|
* @snum: buffer to convert
|
||||||
|
* @error: set to 1 when buffer isn't fully consumed
|
||||||
|
*
|
||||||
|
* These functions are similar to the standard strtoX() functions, but they are
|
||||||
|
* a little bit easier to use if you want to convert full string of digits into
|
||||||
|
* the binary form. The typical usage:
|
||||||
|
*
|
||||||
|
* int error = 0;
|
||||||
|
* unsigned long num;
|
||||||
|
*
|
||||||
|
* num = simple_strtoul(str, &error);
|
||||||
|
* if (error || ... if needed, your check that num is not out of range ...)
|
||||||
|
* error_happened();
|
||||||
|
*/
|
||||||
|
#define simple_strtoX(func, type) \
|
||||||
|
static inline type simple_##func(const char *snum, int *error) \
|
||||||
|
{ \
|
||||||
|
char *endptr; \
|
||||||
|
type ret = func(snum, &endptr, 0); \
|
||||||
|
\
|
||||||
|
if (error && (!*snum || *endptr)) { \
|
||||||
|
errmsg("%s: unable to parse the number '%s'", #func, snum); \
|
||||||
|
*error = 1; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
simple_strtoX(strtol, long int)
|
||||||
|
simple_strtoX(strtoll, long long int)
|
||||||
|
simple_strtoX(strtoul, unsigned long int)
|
||||||
|
simple_strtoX(strtoull, unsigned long long int)
|
||||||
|
|
||||||
|
/* Simple version-printing for utils */
|
||||||
|
#define common_print_version() \
|
||||||
|
do { \
|
||||||
|
printf("%s %s\n", PROGRAM_NAME, VERSION); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#include "libmtd_xalloc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !__MTD_UTILS_COMMON_H__ */
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) International Business Machines Corp., 2006
|
||||||
|
* Copyright (C) 2009 Nokia Corporation
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Author: Artem Bityutskiy
|
||||||
|
*
|
||||||
|
* MTD library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Imported from mtd-utils by dehrenberg */
|
||||||
|
|
||||||
|
#ifndef __LIBMTD_INT_H__
|
||||||
|
#define __LIBMTD_INT_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PROGRAM_NAME "libmtd"
|
||||||
|
|
||||||
|
#define SYSFS_MTD "class/mtd"
|
||||||
|
#define MTD_NAME_PATT "mtd%d"
|
||||||
|
#define MTD_DEV "dev"
|
||||||
|
#define MTD_NAME "name"
|
||||||
|
#define MTD_TYPE "type"
|
||||||
|
#define MTD_EB_SIZE "erasesize"
|
||||||
|
#define MTD_SIZE "size"
|
||||||
|
#define MTD_MIN_IO_SIZE "writesize"
|
||||||
|
#define MTD_SUBPAGE_SIZE "subpagesize"
|
||||||
|
#define MTD_OOB_SIZE "oobsize"
|
||||||
|
#define MTD_REGION_CNT "numeraseregions"
|
||||||
|
#define MTD_FLAGS "flags"
|
||||||
|
|
||||||
|
#define OFFS64_IOCTLS_UNKNOWN 0
|
||||||
|
#define OFFS64_IOCTLS_NOT_SUPPORTED 1
|
||||||
|
#define OFFS64_IOCTLS_SUPPORTED 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* libmtd - MTD library description data structure.
|
||||||
|
* @sysfs_mtd: MTD directory in sysfs
|
||||||
|
* @mtd: MTD device sysfs directory pattern
|
||||||
|
* @mtd_dev: MTD device major/minor numbers file pattern
|
||||||
|
* @mtd_name: MTD device name file pattern
|
||||||
|
* @mtd_type: MTD device type file pattern
|
||||||
|
* @mtd_eb_size: MTD device eraseblock size file pattern
|
||||||
|
* @mtd_size: MTD device size file pattern
|
||||||
|
* @mtd_min_io_size: minimum I/O unit size file pattern
|
||||||
|
* @mtd_subpage_size: sub-page size file pattern
|
||||||
|
* @mtd_oob_size: MTD device OOB size file pattern
|
||||||
|
* @mtd_region_cnt: count of additional erase regions file pattern
|
||||||
|
* @mtd_flags: MTD device flags file pattern
|
||||||
|
* @sysfs_supported: non-zero if sysfs is supported by MTD
|
||||||
|
* @offs64_ioctls: %OFFS64_IOCTLS_SUPPORTED if 64-bit %MEMERASE64,
|
||||||
|
* %MEMREADOOB64, %MEMWRITEOOB64 MTD device ioctls are
|
||||||
|
* supported, %OFFS64_IOCTLS_NOT_SUPPORTED if not, and
|
||||||
|
* %OFFS64_IOCTLS_UNKNOWN if it is not known yet;
|
||||||
|
*
|
||||||
|
* Note, we cannot find out whether 64-bit ioctls are supported by MTD when we
|
||||||
|
* are initializing the library, because this requires an MTD device node.
|
||||||
|
* Indeed, we have to actually call the ioctl and check for %ENOTTY to find
|
||||||
|
* out whether it is supported or not.
|
||||||
|
*
|
||||||
|
* Thus, we leave %offs64_ioctls uninitialized in 'libmtd_open()', and
|
||||||
|
* initialize it later, when corresponding libmtd function is used, and when
|
||||||
|
* we actually have a device node and can invoke an ioctl command on it.
|
||||||
|
*/
|
||||||
|
struct libmtd
|
||||||
|
{
|
||||||
|
char *sysfs_mtd;
|
||||||
|
char *mtd;
|
||||||
|
char *mtd_dev;
|
||||||
|
char *mtd_name;
|
||||||
|
char *mtd_type;
|
||||||
|
char *mtd_eb_size;
|
||||||
|
char *mtd_size;
|
||||||
|
char *mtd_min_io_size;
|
||||||
|
char *mtd_subpage_size;
|
||||||
|
char *mtd_oob_size;
|
||||||
|
char *mtd_region_cnt;
|
||||||
|
char *mtd_flags;
|
||||||
|
unsigned int sysfs_supported:1;
|
||||||
|
unsigned int offs64_ioctls:2;
|
||||||
|
};
|
||||||
|
|
||||||
|
int legacy_libmtd_open(void);
|
||||||
|
int legacy_dev_present(int mtd_num);
|
||||||
|
int legacy_mtd_get_info(struct mtd_info *info);
|
||||||
|
int legacy_get_dev_info(const char *node, struct mtd_dev_info *mtd);
|
||||||
|
int legacy_get_dev_info1(int dev_num, struct mtd_dev_info *mtd);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !__LIBMTD_INT_H__ */
|
|
@ -0,0 +1,384 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 Nokia Corporation
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Author: Artem Bityutskiy
|
||||||
|
*
|
||||||
|
* This file is part of the MTD library. Implements pre-2.6.30 kernels support,
|
||||||
|
* where MTD did not have sysfs interface. The main limitation of the old
|
||||||
|
* kernels was that the sub-page size was not exported to user-space, so it was
|
||||||
|
* not possible to get sub-page size.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Imported from mtd-utils by dehrenberg */
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <mtd/mtd-user.h>
|
||||||
|
|
||||||
|
#include "libmtd.h"
|
||||||
|
#include "libmtd_int.h"
|
||||||
|
#include "libmtd_common.h"
|
||||||
|
|
||||||
|
#define MTD_PROC_FILE "/proc/mtd"
|
||||||
|
#define MTD_DEV_PATT "/dev/mtd%d"
|
||||||
|
#define MTD_DEV_MAJOR 90
|
||||||
|
|
||||||
|
#define PROC_MTD_FIRST "dev: size erasesize name\n"
|
||||||
|
#define PROC_MTD_FIRST_LEN (sizeof(PROC_MTD_FIRST) - 1)
|
||||||
|
#define PROC_MTD_MAX_LEN 4096
|
||||||
|
#define PROC_MTD_PATT "mtd%d: %llx %x"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct proc_parse_info - /proc/mtd parsing information.
|
||||||
|
* @mtd_num: MTD device number
|
||||||
|
* @size: device size
|
||||||
|
* @eb_size: eraseblock size
|
||||||
|
* @name: device name
|
||||||
|
* @buf: contents of /proc/mtd
|
||||||
|
* @data_size: how much data was read into @buf
|
||||||
|
* @pos: next string in @buf to parse
|
||||||
|
*/
|
||||||
|
struct proc_parse_info
|
||||||
|
{
|
||||||
|
int mtd_num;
|
||||||
|
long long size;
|
||||||
|
char name[MTD_NAME_MAX + 1];
|
||||||
|
int eb_size;
|
||||||
|
char *buf;
|
||||||
|
int data_size;
|
||||||
|
char *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int proc_parse_start(struct proc_parse_info *pi)
|
||||||
|
{
|
||||||
|
int fd, ret;
|
||||||
|
|
||||||
|
fd = open(MTD_PROC_FILE, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pi->buf = xmalloc(PROC_MTD_MAX_LEN);
|
||||||
|
|
||||||
|
ret = read(fd, pi->buf, PROC_MTD_MAX_LEN);
|
||||||
|
if (ret == -1) {
|
||||||
|
sys_errmsg("cannot read \"%s\"", MTD_PROC_FILE);
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < PROC_MTD_FIRST_LEN ||
|
||||||
|
memcmp(pi->buf, PROC_MTD_FIRST, PROC_MTD_FIRST_LEN)) {
|
||||||
|
errmsg("\"%s\" does not start with \"%s\"", MTD_PROC_FILE,
|
||||||
|
PROC_MTD_FIRST);
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
pi->data_size = ret;
|
||||||
|
pi->next = pi->buf + PROC_MTD_FIRST_LEN;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_free:
|
||||||
|
free(pi->buf);
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int proc_parse_next(struct proc_parse_info *pi)
|
||||||
|
{
|
||||||
|
int ret, len, pos = pi->next - pi->buf;
|
||||||
|
char *p, *p1;
|
||||||
|
|
||||||
|
if (pos >= pi->data_size) {
|
||||||
|
free(pi->buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sscanf(pi->next, PROC_MTD_PATT, &pi->mtd_num, &pi->size,
|
||||||
|
&pi->eb_size);
|
||||||
|
if (ret != 3)
|
||||||
|
return errmsg("\"%s\" pattern not found", PROC_MTD_PATT);
|
||||||
|
|
||||||
|
p = memchr(pi->next, '\"', pi->data_size - pos);
|
||||||
|
if (!p)
|
||||||
|
return errmsg("opening \" not found");
|
||||||
|
p += 1;
|
||||||
|
pos = p - pi->buf;
|
||||||
|
if (pos >= pi->data_size)
|
||||||
|
return errmsg("opening \" not found");
|
||||||
|
|
||||||
|
p1 = memchr(p, '\"', pi->data_size - pos);
|
||||||
|
if (!p1)
|
||||||
|
return errmsg("closing \" not found");
|
||||||
|
pos = p1 - pi->buf;
|
||||||
|
if (pos >= pi->data_size)
|
||||||
|
return errmsg("closing \" not found");
|
||||||
|
|
||||||
|
len = p1 - p;
|
||||||
|
if (len > MTD_NAME_MAX)
|
||||||
|
return errmsg("too long mtd%d device name", pi->mtd_num);
|
||||||
|
|
||||||
|
memcpy(pi->name, p, len);
|
||||||
|
pi->name[len] = '\0';
|
||||||
|
|
||||||
|
if (p1[1] != '\n')
|
||||||
|
return errmsg("opening \"\n\" not found");
|
||||||
|
pi->next = p1 + 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* legacy_libmtd_open - legacy version of 'libmtd_open()'.
|
||||||
|
*
|
||||||
|
* This function is just checks that MTD is present in the system. Returns
|
||||||
|
* zero in case of success and %-1 in case of failure. In case of failure,
|
||||||
|
* errno contains zero if MTD is not present in the system, or contains the
|
||||||
|
* error code if a real error happened. This is similar to the 'libmtd_open()'
|
||||||
|
* return conventions.
|
||||||
|
*/
|
||||||
|
int legacy_libmtd_open(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(MTD_PROC_FILE, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
errno = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* legacy_dev_presentl - legacy version of 'mtd_dev_present()'.
|
||||||
|
* @info: the MTD device information is returned here
|
||||||
|
*
|
||||||
|
* When the kernel does not provide sysfs files for the MTD subsystem,
|
||||||
|
* fall-back to parsing the /proc/mtd file to determine whether an mtd device
|
||||||
|
* number @mtd_num is present.
|
||||||
|
*/
|
||||||
|
int legacy_dev_present(int mtd_num)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct proc_parse_info pi;
|
||||||
|
|
||||||
|
ret = proc_parse_start(&pi);
|
||||||
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (proc_parse_next(&pi)) {
|
||||||
|
if (pi.mtd_num == mtd_num)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* legacy_mtd_get_info - legacy version of 'mtd_get_info()'.
|
||||||
|
* @info: the MTD device information is returned here
|
||||||
|
*
|
||||||
|
* This function is similar to 'mtd_get_info()' and has the same conventions.
|
||||||
|
*/
|
||||||
|
int legacy_mtd_get_info(struct mtd_info *info)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct proc_parse_info pi;
|
||||||
|
|
||||||
|
ret = proc_parse_start(&pi);
|
||||||
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
info->lowest_mtd_num = INT_MAX;
|
||||||
|
while (proc_parse_next(&pi)) {
|
||||||
|
info->mtd_dev_cnt += 1;
|
||||||
|
if (pi.mtd_num > info->highest_mtd_num)
|
||||||
|
info->highest_mtd_num = pi.mtd_num;
|
||||||
|
if (pi.mtd_num < info->lowest_mtd_num)
|
||||||
|
info->lowest_mtd_num = pi.mtd_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* legacy_get_dev_info - legacy version of 'mtd_get_dev_info()'.
|
||||||
|
* @node: name of the MTD device node
|
||||||
|
* @mtd: the MTD device information is returned here
|
||||||
|
*
|
||||||
|
* This function is similar to 'mtd_get_dev_info()' and has the same
|
||||||
|
* conventions.
|
||||||
|
*/
|
||||||
|
int legacy_get_dev_info(const char *node, struct mtd_dev_info *mtd)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
struct mtd_info_user ui;
|
||||||
|
int fd, ret;
|
||||||
|
loff_t offs = 0;
|
||||||
|
struct proc_parse_info pi;
|
||||||
|
|
||||||
|
if (stat(node, &st)) {
|
||||||
|
sys_errmsg("cannot open \"%s\"", node);
|
||||||
|
if (errno == ENOENT)
|
||||||
|
normsg("MTD subsystem is old and does not support "
|
||||||
|
"sysfs, so MTD character device nodes have "
|
||||||
|
"to exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!S_ISCHR(st.st_mode)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return errmsg("\"%s\" is not a character device", node);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(mtd, '\0', sizeof(struct mtd_dev_info));
|
||||||
|
mtd->major = major(st.st_rdev);
|
||||||
|
mtd->minor = minor(st.st_rdev);
|
||||||
|
|
||||||
|
if (mtd->major != MTD_DEV_MAJOR) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return errmsg("\"%s\" has major number %d, MTD devices have "
|
||||||
|
"major %d", node, mtd->major, MTD_DEV_MAJOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
mtd->mtd_num = mtd->minor / 2;
|
||||||
|
|
||||||
|
fd = open(node, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
return sys_errmsg("cannot open \"%s\"", node);
|
||||||
|
|
||||||
|
if (ioctl(fd, MEMGETINFO, &ui)) {
|
||||||
|
sys_errmsg("MEMGETINFO ioctl request failed");
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ioctl(fd, MEMGETBADBLOCK, &offs);
|
||||||
|
if (ret == -1) {
|
||||||
|
if (errno != EOPNOTSUPP) {
|
||||||
|
sys_errmsg("MEMGETBADBLOCK ioctl failed");
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
mtd->bb_allowed = 0;
|
||||||
|
} else
|
||||||
|
mtd->bb_allowed = 1;
|
||||||
|
|
||||||
|
mtd->type = ui.type;
|
||||||
|
mtd->size = ui.size;
|
||||||
|
mtd->eb_size = ui.erasesize;
|
||||||
|
mtd->min_io_size = ui.writesize;
|
||||||
|
mtd->oob_size = ui.oobsize;
|
||||||
|
|
||||||
|
if (mtd->min_io_size <= 0) {
|
||||||
|
errmsg("mtd%d (%s) has insane min. I/O unit size %d",
|
||||||
|
mtd->mtd_num, node, mtd->min_io_size);
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
if (mtd->eb_size <= 0 || mtd->eb_size < mtd->min_io_size) {
|
||||||
|
errmsg("mtd%d (%s) has insane eraseblock size %d",
|
||||||
|
mtd->mtd_num, node, mtd->eb_size);
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
if (mtd->size <= 0 || mtd->size < mtd->eb_size) {
|
||||||
|
errmsg("mtd%d (%s) has insane size %lld",
|
||||||
|
mtd->mtd_num, node, mtd->size);
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
mtd->eb_cnt = mtd->size / mtd->eb_size;
|
||||||
|
|
||||||
|
switch(mtd->type) {
|
||||||
|
case MTD_ABSENT:
|
||||||
|
errmsg("mtd%d (%s) is removable and is not present",
|
||||||
|
mtd->mtd_num, node);
|
||||||
|
goto out_close;
|
||||||
|
case MTD_RAM:
|
||||||
|
strcpy((char *)mtd->type_str, "ram");
|
||||||
|
break;
|
||||||
|
case MTD_ROM:
|
||||||
|
strcpy((char *)mtd->type_str, "rom");
|
||||||
|
break;
|
||||||
|
case MTD_NORFLASH:
|
||||||
|
strcpy((char *)mtd->type_str, "nor");
|
||||||
|
break;
|
||||||
|
case MTD_NANDFLASH:
|
||||||
|
strcpy((char *)mtd->type_str, "nand");
|
||||||
|
break;
|
||||||
|
case MTD_MLCNANDFLASH:
|
||||||
|
strcpy((char *)mtd->type_str, "mlc-nand");
|
||||||
|
break;
|
||||||
|
case MTD_DATAFLASH:
|
||||||
|
strcpy((char *)mtd->type_str, "dataflash");
|
||||||
|
break;
|
||||||
|
case MTD_UBIVOLUME:
|
||||||
|
strcpy((char *)mtd->type_str, "ubi");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ui.flags & MTD_WRITEABLE)
|
||||||
|
mtd->writable = 1;
|
||||||
|
mtd->subpage_size = mtd->min_io_size;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unfortunately, the device name is not available via ioctl, and
|
||||||
|
* we have to parse /proc/mtd to get it.
|
||||||
|
*/
|
||||||
|
ret = proc_parse_start(&pi);
|
||||||
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (proc_parse_next(&pi)) {
|
||||||
|
if (pi.mtd_num == mtd->mtd_num) {
|
||||||
|
strcpy((char *)mtd->name, pi.name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errmsg("mtd%d not found in \"%s\"", mtd->mtd_num, MTD_PROC_FILE);
|
||||||
|
errno = ENOENT;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
out_close:
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* legacy_get_dev_info1 - legacy version of 'mtd_get_dev_info1()'.
|
||||||
|
* @node: name of the MTD device node
|
||||||
|
* @mtd: the MTD device information is returned here
|
||||||
|
*
|
||||||
|
* This function is similar to 'mtd_get_dev_info1()' and has the same
|
||||||
|
* conventions.
|
||||||
|
*/
|
||||||
|
int legacy_get_dev_info1(int mtd_num, struct mtd_dev_info *mtd)
|
||||||
|
{
|
||||||
|
char node[sizeof(MTD_DEV_PATT) + 20];
|
||||||
|
|
||||||
|
sprintf(node, MTD_DEV_PATT, mtd_num);
|
||||||
|
return legacy_get_dev_info(node, mtd);
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* memory wrappers
|
||||||
|
*
|
||||||
|
* Copyright (c) Artem Bityutskiy, 2007, 2008
|
||||||
|
* Copyright 2001, 2002 Red Hat, Inc.
|
||||||
|
* 2001 David A. Schleef <ds@lineo.com>
|
||||||
|
* 2002 Axis Communications AB
|
||||||
|
* 2001, 2002 Erik Andersen <andersen@codepoet.org>
|
||||||
|
* 2004 University of Szeged, Hungary
|
||||||
|
* 2006 KaiGai Kohei <kaigai@ak.jp.nec.com>
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MTD_UTILS_XALLOC_H__
|
||||||
|
#define __MTD_UTILS_XALLOC_H__
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark these functions as unused so that gcc does not emit warnings
|
||||||
|
* when people include this header but don't use every function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static void *xmalloc(size_t size)
|
||||||
|
{
|
||||||
|
void *ptr = malloc(size);
|
||||||
|
|
||||||
|
if (ptr == NULL && size != 0)
|
||||||
|
sys_errmsg_die("out of memory");
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static void *xcalloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
void *ptr = calloc(nmemb, size);
|
||||||
|
|
||||||
|
if (ptr == NULL && nmemb != 0 && size != 0)
|
||||||
|
sys_errmsg_die("out of memory");
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static void *xzalloc(size_t size)
|
||||||
|
{
|
||||||
|
return xcalloc(1, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static void *xrealloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
ptr = realloc(ptr, size);
|
||||||
|
if (ptr == NULL && size != 0)
|
||||||
|
sys_errmsg_die("out of memory");
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static char *xstrdup(const char *s)
|
||||||
|
{
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
return NULL;
|
||||||
|
t = strdup(s);
|
||||||
|
if (t == NULL)
|
||||||
|
sys_errmsg_die("out of memory");
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _GNU_SOURCE
|
||||||
|
|
||||||
|
__attribute__((unused))
|
||||||
|
static int xasprintf(char **strp, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
cnt = vasprintf(strp, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (cnt == -1)
|
||||||
|
sys_errmsg_die("out of memory");
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !__MTD_UTILS_XALLOC_H__ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue