initial commit
This commit is contained in:
commit
ed2576f160
|
@ -0,0 +1,5 @@
|
|||
.vscode/*
|
||||
.cmake/*
|
||||
.xmake/*
|
||||
build/*
|
||||
app.log
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "imgproc/imageprocess"]
|
||||
path = imgproc/imageprocess
|
||||
url = https://gitee.com/huagaochina/ImageProcess.git
|
|
@ -0,0 +1,52 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
if(CMAKE_HOST_WIN32)
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_C_COMPILER_WORKS 1)
|
||||
set(CMAKE_CXX_COMPILER_WORKS 1)
|
||||
set(tools D:/arm-build/gcc-linaro-6.2.1-2016.11-i686-mingw32_aarch64-linux-gnu/bin)
|
||||
set(CMAKE_CXX_COMPILER ${tools}/aarch64-linux-gnu-g++.exe)
|
||||
set(CMAKE_C_COMPILER ${tools}/aarch64-linux-gnu-gcc.exe)
|
||||
set(CMAKE_FIND_ROOT_PATH D:/arm-build/gcc-linaro-6.2.1-2016.11-i686-mingw32_aarch64-linux-gnu/aarch64-linux-gnu/libc )
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
endif()
|
||||
project(hgscanner_boardsys)
|
||||
# 加入一个配置头文件,用于处理 CMake 对源码的设置
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/config.h.in"
|
||||
"${PROJECT_SOURCE_DIR}/packages/common.pkg/include/config.h"
|
||||
)
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
# set(CMAKE_BUILD_TYPE Release)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -DNDEBUG")
|
||||
add_subdirectory(applog)
|
||||
add_subdirectory(capimage)
|
||||
add_subdirectory(deviceio)
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(fpgaupdate)
|
||||
add_subdirectory(imgproc)
|
||||
add_subdirectory(keymonitor)
|
||||
add_subdirectory(motorcontroller)
|
||||
add_subdirectory(motorboard)
|
||||
add_subdirectory(regs)
|
||||
add_subdirectory(scanner)
|
||||
add_subdirectory(scanservice)
|
||||
add_subdirectory(service)
|
||||
add_subdirectory(testcapimage)
|
||||
add_subdirectory(testimgproc)
|
||||
add_subdirectory(testdisplay)
|
||||
add_subdirectory(testkeymonitor)
|
||||
add_subdirectory(testlcd)
|
||||
add_subdirectory(testmotorboard)
|
||||
add_subdirectory(testregs)
|
||||
add_subdirectory(testscanner)
|
||||
add_subdirectory(testusb)
|
||||
add_subdirectory(testwakeup)
|
||||
add_subdirectory(usb)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
project(applog)
|
||||
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}/../packages/common.pkg/include
|
||||
|
||||
)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
|
|
@ -0,0 +1,121 @@
|
|||
#include "applog.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
#include "spdlog/sinks/basic_file_sink.h"
|
||||
#include "spdlog/sinks/rotating_file_sink.h"
|
||||
#include "stringex.hpp"
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
inline std::string string_toupper(const std::string& str)
|
||||
{
|
||||
std::string s = str;
|
||||
transform(s.begin(), s.end(), s.begin(), toupper);
|
||||
return s;
|
||||
}
|
||||
|
||||
void log_init(const std::string& name, bool benv)
|
||||
{
|
||||
if(spdlog::get(name))
|
||||
return;
|
||||
|
||||
const auto max_size = 1048576 * 5;
|
||||
const auto max_files = 3;
|
||||
|
||||
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||
char *pathvar = getenv(("APP_" + string_toupper(name) + "_CONSOLE_LOG").c_str());
|
||||
console_sink->set_level(pathvar ? std::min(spdlog::level::from_str(pathvar), spdlog::level::off) : spdlog::level::off);
|
||||
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("app.log", max_size, max_files);
|
||||
pathvar = getenv(("APP_" + string_toupper(name) + "_FILE_LOG").c_str());
|
||||
file_sink->set_level(pathvar ? std::min(spdlog::level::from_str(pathvar), spdlog::level::off) : spdlog::level::off);
|
||||
auto logger = std::shared_ptr<spdlog::logger>(new spdlog::logger(name, {console_sink, file_sink}));
|
||||
pathvar = getenv(("APP_" + string_toupper(name) + "_LOG").c_str());
|
||||
logger->set_level(pathvar ? std::min(spdlog::level::from_str(pathvar), spdlog::level::off) : spdlog::level::off);
|
||||
spdlog::register_logger(logger);
|
||||
}
|
||||
|
||||
void log_info(const std::string& name, const std::string& msg)
|
||||
{
|
||||
if(auto log = spdlog::get(name))
|
||||
{
|
||||
log->info(msg);
|
||||
log->flush();
|
||||
}
|
||||
}
|
||||
|
||||
void log_warn(const std::string& name, const std::string& msg)
|
||||
{
|
||||
if (auto log = spdlog::get(name))
|
||||
{
|
||||
log->warn(msg);
|
||||
log->flush();
|
||||
}
|
||||
}
|
||||
|
||||
void log_trace(const std::string& name, const std::string& msg)
|
||||
{
|
||||
if (auto log = spdlog::get(name))
|
||||
{
|
||||
log->trace(msg);
|
||||
log->flush();
|
||||
}
|
||||
}
|
||||
|
||||
void log_debug(const std::string& name, const std::string& msg)
|
||||
{
|
||||
if (auto log = spdlog::get(name))
|
||||
{
|
||||
log->debug(msg);
|
||||
log->flush();
|
||||
}
|
||||
}
|
||||
|
||||
void log_error(const std::string& name, const std::string& msg)
|
||||
{
|
||||
if (auto log = spdlog::get(name))
|
||||
{
|
||||
log->error(msg);
|
||||
log->flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void log_critical(const std::string name, const std::string& msg)
|
||||
{
|
||||
if (auto log = spdlog::get(name))
|
||||
{
|
||||
log->critical(msg);
|
||||
log->flush();
|
||||
}
|
||||
}
|
||||
|
||||
bool log_set_level(const std::string& name, int type ,int level)
|
||||
{
|
||||
if (auto log = spdlog::get(name))
|
||||
{
|
||||
spdlog::level::level_enum actLevel = (spdlog::level::level_enum)std::min(std::max((int)spdlog::level::trace, level), (int)spdlog::level::off);
|
||||
if(type < log->sinks().size())
|
||||
log->sinks()[type]->set_level(actLevel);
|
||||
else
|
||||
log->set_level(actLevel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool log_get_level(const std::string& name, int type ,int& level)
|
||||
{
|
||||
if (auto log = spdlog::get(name))
|
||||
{
|
||||
if(type < log->sinks().size())
|
||||
level = log->sinks()[type]->level();
|
||||
else
|
||||
level = log->level();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#define LOG_INIT() log_init(loggername, true)
|
||||
#define LOG_INITX() log_init(loggername, false)
|
||||
#define LOG_INFO(X) log_info(loggername, X)
|
||||
#define LOG_WARN(X) log_warn(loggername, X)
|
||||
#define LOG_TRACE(X) log_trace(loggername, X)
|
||||
#define LOG_DEBUG(X) log_debug(loggername, X)
|
||||
#define LOG_ERROR(X) log_error(loggername, X)
|
||||
#define LOG_CRITICAL(X) log_critical(loggername, X)
|
||||
|
||||
void log_init(const std::string& name, bool benv);
|
||||
void log_info(const std::string& name, const std::string& msg);
|
||||
void log_warn(const std::string& name, const std::string& msg);
|
||||
void log_trace(const std::string& name, const std::string& msg);
|
||||
void log_debug(const std::string& name, const std::string& msg);
|
||||
void log_error(const std::string& name, const std::string& msg);
|
||||
void log_critical(const std::string& name, const std::string& msg);
|
||||
bool log_set_level(const std::string& name, int type ,int level);
|
||||
bool log_get_level(const std::string& name, int type ,int& level);
|
|
@ -0,0 +1,301 @@
|
|||
#include "CImageMerge.h"
|
||||
#include <vector>
|
||||
CImageMerge::CImageMerge()
|
||||
{
|
||||
}
|
||||
CImageMerge::~CImageMerge()
|
||||
{
|
||||
}
|
||||
cv::Mat CImageMerge::MergeImage(cv::Mat &srcMat, int dstwidth, int dstheight)
|
||||
{
|
||||
cv::Mat retMat(dstheight, dstwidth, CV_8UC3);
|
||||
|
||||
if (!srcMat.empty())
|
||||
{
|
||||
std::vector<cv::Mat> ch_mats;
|
||||
int blockcnt = 12;
|
||||
int spitWidth = srcMat.cols / blockcnt;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + j), 0, spitWidth, dstheight)));
|
||||
}
|
||||
cv::merge(ch_mats, retMat(cv::Rect(spitWidth * i, 0, spitWidth, dstheight)));
|
||||
ch_mats.clear();
|
||||
}
|
||||
return retMat;
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat CImageMerge::MergeImage(bool iscolor, cv::Mat &srcMat, int dstwidth, int dstheight, unsigned int fgpaversion)
|
||||
{
|
||||
int blockcnt = 12;
|
||||
int spitWidth = srcMat.cols / blockcnt;
|
||||
int abortwidth; // = spitWidth == 3888 ? 432 : (spitWidth == 2592 ? 216 : 144);
|
||||
if (!iscolor) // 灰度
|
||||
{
|
||||
abortwidth = spitWidth == 1296 ? 432 : (spitWidth == 648 ? 216 : 144);
|
||||
}
|
||||
else
|
||||
{
|
||||
abortwidth = spitWidth == 3888 ? 432 : (spitWidth == 1944 ? 216 : 144);
|
||||
}
|
||||
if (fgpaversion == 0x00090002)
|
||||
{
|
||||
int blockcnt = iscolor ? 18 : 6;
|
||||
int spitWidth = srcMat.cols / blockcnt / 2; // 一面的灰度图像宽度
|
||||
int abortwidth = spitWidth == 1296 ? 432 : (spitWidth == 648 ? 216 : 144);
|
||||
|
||||
cv::Mat dst(dstheight, dstwidth - 2 * abortwidth, CV_8UC(iscolor ? 3 : 1));
|
||||
if (!iscolor)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int j = 0; j < 6; j++)
|
||||
{
|
||||
int index = i == 0 ? 5 : 11;
|
||||
int bandindex = (i * 6 + j);
|
||||
if (bandindex == 0 || bandindex == 11)
|
||||
{
|
||||
if (bandindex == 0)
|
||||
srcMat(cv::Rect(bandindex * spitWidth, 0, spitWidth - abortwidth, srcMat.rows)).copyTo(dst(cv::Rect(spitWidth * (index - j), 0, spitWidth - abortwidth, srcMat.rows)));
|
||||
else
|
||||
srcMat(cv::Rect(bandindex * spitWidth + abortwidth, 0, spitWidth - abortwidth, srcMat.rows)).copyTo(dst(cv::Rect(spitWidth * (index - j) - abortwidth, 0, spitWidth - abortwidth, srcMat.rows)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bandindex >= 6)
|
||||
srcMat(cv::Rect(bandindex * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(dst(cv::Rect(spitWidth * (index - j) - 2 * abortwidth, 0, spitWidth, srcMat.rows)));
|
||||
else
|
||||
srcMat(cv::Rect(bandindex * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(dst(cv::Rect(spitWidth * (index - j), 0, spitWidth, srcMat.rows)));
|
||||
}
|
||||
}
|
||||
}
|
||||
srcMat.release();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<cv::Mat> m_splits = {
|
||||
cv::Mat(dstheight, dstwidth - 2 * abortwidth, CV_8UC1),
|
||||
cv::Mat(dstheight, dstwidth - 2 * abortwidth, CV_8UC1),
|
||||
cv::Mat(dstheight, dstwidth - 2 * abortwidth, CV_8UC1)};
|
||||
int item_index[3][4] = {
|
||||
{11, 2, 35, 26}, // R
|
||||
{17, 8, 29, 20}, // B
|
||||
{14, 5, 32, 23} // G
|
||||
};
|
||||
|
||||
for (size_t j = 0; j < 3; j++)
|
||||
{
|
||||
// Front
|
||||
srcMat(cv::Rect((item_index[j][0] - 0) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 0, 0, spitWidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][0] - 1) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 1, 0, spitWidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][0] - 2) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 2, 0, spitWidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][1] - 0) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 3, 0, spitWidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][1] - 1) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 4, 0, spitWidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][1] - 2) * spitWidth, 0, spitWidth - abortwidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 5, 0, spitWidth - abortwidth, srcMat.rows)));
|
||||
// Back
|
||||
srcMat(cv::Rect((item_index[j][2] - 0) * spitWidth + abortwidth, 0, spitWidth - abortwidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 6 - abortwidth, 0, spitWidth - abortwidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][2] - 1) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 7 - 2 * abortwidth, 0, spitWidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][2] - 2) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 8 - 2 * abortwidth, 0, spitWidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][3] - 0) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 9 - 2 * abortwidth, 0, spitWidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][3] - 1) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 10 - 2 * abortwidth, 0, spitWidth, srcMat.rows)));
|
||||
srcMat(cv::Rect((item_index[j][3] - 2) * spitWidth, 0, spitWidth, srcMat.rows)).copyTo(m_splits[j](cv::Rect(spitWidth * 11 - 2 * abortwidth, 0, spitWidth, srcMat.rows)));
|
||||
}
|
||||
cv::merge(m_splits, dst);
|
||||
m_splits.clear();
|
||||
}
|
||||
srcMat.release();
|
||||
// static int index=0;
|
||||
// cv::imwrite(std::to_string(++index)+".bmp",dst);
|
||||
return dst;
|
||||
}
|
||||
else if (fgpaversion == 0x00090001)
|
||||
{
|
||||
int blockcnt = 12;
|
||||
int spitWidth = srcMat.cols / blockcnt;
|
||||
int abortwidth; // = spitWidth == 3888 ? 432 : (spitWidth == 2592 ? 216 : 144);
|
||||
if (!iscolor) // 灰度
|
||||
{
|
||||
abortwidth = spitWidth == 1296 ? 432 : (spitWidth == 648 ? 216 : 144);
|
||||
}
|
||||
else
|
||||
{
|
||||
abortwidth = spitWidth == 3888 ? 432 : (spitWidth == 1944 ? 216 : 144);
|
||||
}
|
||||
|
||||
cv::Mat dst(dstheight, dstwidth - abortwidth * 2, CV_8UC(iscolor ? 3 : 1));
|
||||
if (!iscolor)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
srcMat(cv::Rect((dstwidth / 2 + abortwidth) * i, 0, dstwidth / 2 - abortwidth, dstheight)).copyTo(dst(cv::Rect(dst.cols / 2 * i, 0, dst.cols / 2, dstheight)));
|
||||
}
|
||||
srcMat.release();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<cv::Mat> m_splits;
|
||||
std::vector<int> m_index = {0, 3, 8, 11, 2, 5, 6, 9, 1, 4, 7, 10};
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int startindex = i == 0 ? 0 : (i == 1 ? 4 : 8);
|
||||
cv::Mat t_mat(dstheight, dstwidth - abortwidth * 2, CV_8UC1);
|
||||
srcMat(cv::Rect(spitWidth * m_index[startindex + 0], 0, spitWidth, dstheight)).copyTo(t_mat(cv::Rect(0, 0, spitWidth, dstheight)));
|
||||
srcMat(cv::Rect(spitWidth * m_index[startindex + 1], 0, spitWidth - abortwidth, dstheight)).copyTo(t_mat(cv::Rect(spitWidth, 0, spitWidth - abortwidth, dstheight)));
|
||||
srcMat(cv::Rect(spitWidth * m_index[startindex + 2] + abortwidth, 0, spitWidth - abortwidth, dstheight)).copyTo(t_mat(cv::Rect(spitWidth * 2 - abortwidth, 0, spitWidth - abortwidth, dstheight)));
|
||||
srcMat(cv::Rect(spitWidth * m_index[startindex + 3], 0, spitWidth, dstheight)).copyTo(t_mat(cv::Rect(spitWidth * 3 - abortwidth * 2, 0, spitWidth, dstheight)));
|
||||
m_splits.push_back(t_mat);
|
||||
}
|
||||
cv::merge(m_splits, dst);
|
||||
m_splits.clear();
|
||||
}
|
||||
srcMat.release();
|
||||
return dst;
|
||||
}
|
||||
else if (fgpaversion == 0x0009000a)
|
||||
{
|
||||
auto switchblock = [](std::vector<std::pair<int, int>> v, cv::Mat &src, cv::Mat &dst, int block_width, int block_height, int abortwidth)
|
||||
{
|
||||
int copyindex = 0;
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
{
|
||||
if (v[i].second == 5 || v[i].second == 6)
|
||||
{
|
||||
src(cv::Rect(v[i].second == 6 ? block_width * v[i].first + abortwidth : block_width * v[i].first, 0, block_width - abortwidth, block_height)).copyTo(dst(cv::Rect(copyindex, 0, block_width - abortwidth, block_height)));
|
||||
copyindex += block_width - abortwidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
src(cv::Rect(block_width * v[i].first, 0, block_width, block_height)).copyTo(dst(cv::Rect(copyindex, 0, block_width, block_height)));
|
||||
copyindex += block_width;
|
||||
}
|
||||
}
|
||||
};
|
||||
std::vector<std::pair<int, int>> v{{3, 0}, {5, 1}, {4, 2}, {1, 3}, {0, 4}, {2, 5}, {10, 6}, {9, 7}, {11, 8}, {6, 9}, {8, 10}, {7, 11}};
|
||||
if (!iscolor)
|
||||
{
|
||||
int abortwidth = srcMat.cols / 12 == 1296 ? 432 : (srcMat.cols / 12 == 648 ? 216 : 144);
|
||||
cv::Mat dst(srcMat.rows, srcMat.cols - abortwidth * 2, CV_8UC1);
|
||||
switchblock(v, srcMat, dst, srcMat.cols / 12, srcMat.rows, abortwidth);
|
||||
return dst;
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Mat retMat(srcMat.rows, srcMat.cols / 3, CV_8UC3);
|
||||
int spitWidth = srcMat.cols / 12;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
// 1 2 0
|
||||
std::vector<cv::Mat> ch_mats;
|
||||
if (i < 2)
|
||||
{
|
||||
ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 0), 0, spitWidth, srcMat.rows)));
|
||||
ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 2), 0, spitWidth, srcMat.rows)));
|
||||
ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 1), 0, spitWidth, srcMat.rows)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 2), 0, spitWidth, srcMat.rows)));
|
||||
ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 0), 0, spitWidth, srcMat.rows)));
|
||||
ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + 1), 0, spitWidth, srcMat.rows)));
|
||||
}
|
||||
cv::merge(ch_mats, retMat(cv::Rect(spitWidth * i, 0, spitWidth, srcMat.rows)));
|
||||
ch_mats.clear();
|
||||
}
|
||||
int abortwidth = retMat.cols / 12 == 1296 ? 432 : (retMat.cols / 12 == 648 ? 216 : 144);
|
||||
cv::Mat dst(retMat.rows, retMat.cols - abortwidth * 2, CV_8UC3);
|
||||
switchblock(v, retMat, dst, retMat.cols / 12, retMat.rows, abortwidth);
|
||||
printf(" dst.cols = %d dst.rows = %d dst.channels = %d \n", dst.cols, dst.rows, dst.channels());
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
else if (fgpaversion == 0x0009000b)
|
||||
{
|
||||
int copy_size = 0;
|
||||
int ratio = iscolor ? 3 : 1;
|
||||
int spitWidth = srcMat.cols / 12;
|
||||
int abortwidth = spitWidth == 1296 ? 432 : (spitWidth == 648 ? 216 : 144);
|
||||
if (iscolor)
|
||||
abortwidth = spitWidth == 3888 ? 432 : (spitWidth == 1944 ? 216 : 144);
|
||||
spitWidth /= ratio;
|
||||
cv::Mat dst(srcMat.rows, srcMat.cols / (iscolor ? 3 : 1) - abortwidth * 2, CV_8UC(iscolor ? 3 : 1));
|
||||
std::vector<std::pair<int, int>> v = {{spitWidth * (3 * ratio + 1), spitWidth}, {spitWidth * (3 * ratio), spitWidth}, {spitWidth * (3 * ratio + 2), spitWidth}, {spitWidth * 0, spitWidth}, {spitWidth * 2, spitWidth}, {spitWidth * 1, spitWidth - abortwidth}, {spitWidth * (9 * ratio + 1) + abortwidth, spitWidth - abortwidth}, {spitWidth * (9 * ratio), spitWidth}, {spitWidth * (9 * ratio + 2), spitWidth}, {spitWidth * (6 * ratio), spitWidth}, {spitWidth * (6 * ratio + 2), spitWidth}, {spitWidth * (6 * ratio + 1), spitWidth}};
|
||||
if (!iscolor)
|
||||
{
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
{
|
||||
srcMat(cv::Rect(v[i].first, 0, v[i].second, srcMat.rows)).copyTo(dst(cv::Rect(copy_size, 0, v[i].second, srcMat.rows)));
|
||||
copy_size += v[i].second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<cv::Mat> m_splits;
|
||||
std::vector<int> m_index_f = {0, 2, 1};
|
||||
std::vector<int> m_index_b = {2, 0, 1};
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
cv::Mat tmp_dst(srcMat.rows, srcMat.cols / (iscolor ? 3 : 1) - abortwidth * 2, CV_8UC1);
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
{
|
||||
if (i > 5)
|
||||
srcMat(cv::Rect(v[i].first + m_index_b[j] * 3 * spitWidth, 0, v[i].second, srcMat.rows)).copyTo(tmp_dst(cv::Rect(copy_size, 0, v[i].second, srcMat.rows)));
|
||||
else
|
||||
srcMat(cv::Rect(v[i].first + m_index_f[j] * 3 * spitWidth, 0, v[i].second, srcMat.rows)).copyTo(tmp_dst(cv::Rect(copy_size, 0, v[i].second, srcMat.rows)));
|
||||
copy_size += v[i].second;
|
||||
}
|
||||
copy_size = 0;
|
||||
m_splits.push_back(tmp_dst);
|
||||
}
|
||||
cv::merge(m_splits, dst);
|
||||
m_splits.clear();
|
||||
}
|
||||
srcMat.release();
|
||||
return dst;
|
||||
}
|
||||
else if (fgpaversion == 0x0009000c)
|
||||
{
|
||||
// cv::imwrite("src.bmp",srcMat);
|
||||
cv::Mat dst(dstheight, dstwidth - abortwidth * 2, CV_8UC(iscolor ? 3 : 1));
|
||||
int copy_size = 0;
|
||||
int ratio = iscolor ? 3 : 1;
|
||||
spitWidth /= ratio;
|
||||
std::vector<std::pair<int, int>> v = {{spitWidth * (ratio * 3 + 2), spitWidth}, {spitWidth * (ratio * 3 + 1), spitWidth}, {spitWidth * (ratio * 3), spitWidth}, {spitWidth * 2, spitWidth}, {spitWidth, spitWidth}, {0, spitWidth - abortwidth}, {spitWidth * (ratio * 9 + 2) + abortwidth, spitWidth - abortwidth}, {spitWidth * (ratio * 9 + 1), spitWidth}, {spitWidth * (ratio * 9), spitWidth}, {spitWidth * (ratio * 6 + 2), spitWidth}, {spitWidth * (ratio * 6 + 1), spitWidth}, {spitWidth * (ratio * 6), spitWidth}};
|
||||
if (!iscolor)
|
||||
{
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
{
|
||||
srcMat(cv::Rect(v[i].first, 0, v[i].second, srcMat.rows)).copyTo(dst(cv::Rect(copy_size, 0, v[i].second, srcMat.rows)));
|
||||
copy_size += v[i].second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<cv::Mat> m_splits;
|
||||
std::vector<int> m_index_f = {0, 2, 1};
|
||||
std::vector<int> m_index_b = {2, 0, 1};
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
cv::Mat tmp_dst(dstheight, dstwidth - abortwidth * 2, CV_8UC1);
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
{
|
||||
if (i > 5)
|
||||
srcMat(cv::Rect(v[i].first + m_index_b[j] * 3 * spitWidth, 0, v[i].second, srcMat.rows)).copyTo(tmp_dst(cv::Rect(copy_size, 0, v[i].second, srcMat.rows)));
|
||||
else
|
||||
srcMat(cv::Rect(v[i].first + m_index_f[j] * 3 * spitWidth, 0, v[i].second, srcMat.rows)).copyTo(tmp_dst(cv::Rect(copy_size, 0, v[i].second, srcMat.rows)));
|
||||
copy_size += v[i].second;
|
||||
}
|
||||
copy_size = 0;
|
||||
m_splits.push_back(tmp_dst);
|
||||
}
|
||||
cv::merge(m_splits, dst);
|
||||
m_splits.clear();
|
||||
}
|
||||
srcMat.release();
|
||||
return dst;
|
||||
}
|
||||
return srcMat;
|
||||
}
|
|
@ -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);
|
||||
cv::Mat MergeImage(bool iscolor, cv::Mat &srcMat, int dstwidth, int dstheight, unsigned int fgpaversion = 0x00090001);
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
project(capimage)
|
||||
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)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/imageprocess DIR_IMGPROC)
|
||||
file(GLOB DIR_HEADS "${PROJECT_SOURCE_DIR}/*.h" "${PROJECT_SOURCE_DIR}/*.hpp")
|
||||
set(DIR_SRCS ${DIR_SRCS} ${DIR_HEADS} ${DIR_IMGPROC})
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC ${DIR_SRCS} ${DIR_IMGPROC})
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_SOURCE_DIR}/../packages/common.pkg/include
|
||||
${PROJECT_SOURCE_DIR}/../regs
|
||||
${PROJECT_SOURCE_DIR}/../deviceio
|
||||
${PROJECT_SOURCE_DIR}/../applog
|
||||
)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
|
|
@ -0,0 +1,67 @@
|
|||
#pragma once
|
||||
#include <sstream>
|
||||
|
||||
#define LIGHT_DIFF(maxthre, x) ((maxthre)-x)
|
||||
#define BLACK_DIFF(x) (8 - x)
|
||||
#define FMT_STEP(x) \
|
||||
do \
|
||||
{ \
|
||||
if (x < 1 && x > 0) \
|
||||
{ \
|
||||
x = 1; \
|
||||
} \
|
||||
if (step < 0 && step > -1) \
|
||||
{ \
|
||||
x = -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct FPGAConfigParam
|
||||
{
|
||||
unsigned int ExposureF[3]; // RGB
|
||||
unsigned int GainF[6]; // 123456
|
||||
unsigned int OffsetF[6]; // 123456
|
||||
unsigned int ExposureB[3]; // RGB
|
||||
unsigned int GainB[6]; // 123456
|
||||
unsigned int OffsetB[6]; // 123456
|
||||
unsigned int DpiMode;
|
||||
unsigned int ColorMode;
|
||||
unsigned int MaxBright;
|
||||
unsigned int MaxExp;
|
||||
unsigned int Sp;
|
||||
unsigned int HRatio;
|
||||
unsigned int VRatio;
|
||||
std::string LutPath;
|
||||
std::string TextLutPath;
|
||||
std::string Flat_BwPath;
|
||||
std::string Flat_WhitePath;
|
||||
};
|
||||
|
||||
struct FPGAConfigParam_8478
|
||||
{
|
||||
unsigned int ExposureF[3]; // RGB
|
||||
unsigned int GainF_R[9]; // 123456
|
||||
unsigned int OffsetF_R[9]; // 123456
|
||||
unsigned int GainF_G[9]; // 123456
|
||||
unsigned int OffsetF_G[9]; // 123456
|
||||
unsigned int GainF_B[9]; // 123456
|
||||
unsigned int OffsetF_B[9]; // 123456
|
||||
unsigned int ExposureB[3]; // RGB
|
||||
unsigned int GainB_R[9]; // 123456
|
||||
unsigned int OffsetB_R[9]; // 123456
|
||||
unsigned int GainB_G[9]; // 123456
|
||||
unsigned int OffsetB_G[9]; // 123456
|
||||
unsigned int GainB_B[9]; // 123456
|
||||
unsigned int OffsetB_B[9]; // 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,845 @@
|
|||
#include "Capturer.h"
|
||||
#include "DevUtil.h"
|
||||
#include <thread>
|
||||
#include <time.h>
|
||||
#include <sstream>
|
||||
#include "Gpio.h"
|
||||
#include "FpgaComm.h"
|
||||
#include "gvideoisp1.h"
|
||||
#include "config.h"
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include "applog.h"
|
||||
#include "stringex.hpp"
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "filetools.h"
|
||||
#include "CameraParam.h"
|
||||
#include "correct_ultis.h"
|
||||
|
||||
using namespace std;
|
||||
#define LOG_PATH "/usr/local/correct.log"
|
||||
FileTools ft(LOG_PATH);
|
||||
|
||||
static std::string loggername = "Capturer";
|
||||
|
||||
bool isAutoCorrect = true;
|
||||
double Radio = 1;
|
||||
cv::Mat mBuffMat;
|
||||
cv::Mat out;
|
||||
|
||||
Capturer::Capturer()
|
||||
: vdd_cis_3voff_pin(new GpioOut(CIS_3v3_Off)),
|
||||
vdd_vis_5ven_pin(new GpioOut(CIS_5v_En)),
|
||||
reset_pin(new GpioOut(Fpga_Reset)),
|
||||
image_in_transfer_pin(new Gpio(Image_In_Transfer)),
|
||||
initDone_pin(new Gpio(Fpga_InitDone)),
|
||||
fpgaLoad(new GpioOut(Fpga_Load)),
|
||||
bcorrecting(false)
|
||||
{
|
||||
LOG_INIT();
|
||||
fpgaComm.reset(new FpgaComm());
|
||||
fpga_reset();
|
||||
fpgaComm->resetADC();
|
||||
fpgaComm->setDelayTime(0X3e8);
|
||||
|
||||
video.reset(new VIDEO_CLASS());
|
||||
}
|
||||
|
||||
Capturer::~Capturer()
|
||||
{
|
||||
}
|
||||
|
||||
void Capturer::Fpga_regsAccess_reset(bool enable)
|
||||
{
|
||||
}
|
||||
void Capturer::open()
|
||||
{
|
||||
cisconfigs = getcisparams();
|
||||
int height = 6000;
|
||||
set_sp(0x0208);
|
||||
fpgaComm->setColorMode(1);
|
||||
// int height = 2000;
|
||||
// set_sp(0x0bf0);
|
||||
// fpgaComm->setColorMode(0);
|
||||
fpgaComm->setDpi(1);
|
||||
fpgaComm->setSample(256);
|
||||
fpgaComm->enableLed(true);
|
||||
// 设置曝光值等
|
||||
int exp[2][3];
|
||||
int gains[2][6];
|
||||
int offsets[2][6];
|
||||
for (int i = 0; i < 3; i++)
|
||||
set_expo(i, 0x300); // 0x1b0);
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
set_gain(i, 300);
|
||||
set_offset(i, 150);
|
||||
}
|
||||
|
||||
fpgaComm->setFrameHeight(12);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
fpgaComm->capture();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
video.reset(new VIDEO_CLASS());
|
||||
|
||||
video->open(1632, height);
|
||||
fpgaComm->setFrameHeight(12);
|
||||
for (int i = 0; i < 1; i++)
|
||||
{
|
||||
fpgaComm->capture();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
fpgaComm->setFrameHeight(height);
|
||||
}
|
||||
static int val = 0;
|
||||
static double exp_ratio = 0.1;
|
||||
void Capturer::open(HGScanConfig config, FPGAConfigParam fpgaparam)
|
||||
{
|
||||
if (val > 4000)
|
||||
val = 0;
|
||||
|
||||
if (exp_ratio > 2.0)
|
||||
exp_ratio = 0.1;
|
||||
cisconfigs = getcisparams();
|
||||
auto hgsize = papersMap[(PaperSize)config.g200params.paper];
|
||||
int height = hgsize.height;
|
||||
fpgaComm->setColorMode(config.g200params.color ? 1 : 0);
|
||||
auto info = Get_static_jsonconfig().getscannerinfo();
|
||||
// set_sp(config.g200params.color ? cisconfigs.color.sp : cisconfigs.gray.sp); //0x03fa : 0x0bf0
|
||||
int clrsp, graysp;
|
||||
// if (scannerSp.count((SpeedMode)info.speedmode) <= 0)
|
||||
// {
|
||||
// #ifdef G200
|
||||
// clrsp = scannerSp[SpeedMode::PPM100].colorSp;
|
||||
// graysp = scannerSp[SpeedMode::PPM100].colorSp;
|
||||
// #else
|
||||
// clrsp = scannerSp[SpeedMode::PPM70].colorSp;
|
||||
// graysp = scannerSp[SpeedMode::PPM70].colorSp;
|
||||
// #endif
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// clrsp = scannerSp[(SpeedMode)info.speedmode].colorSp;
|
||||
// graysp = scannerSp[(SpeedMode)info.speedmode].colorSp;
|
||||
// }
|
||||
clrsp = info.color_sp;
|
||||
graysp = info.gray_sp;
|
||||
set_sp(config.g200params.color ? clrsp : graysp);
|
||||
printf("\n capture color sp =%d, gray sp =%d", clrsp, graysp);
|
||||
// set_sp(config.g200params.color ? 0x335 : 0x99f); //G100 0x438 0xca8 60 ppm 0x335 : 0x99f 100ppm
|
||||
// G200 SP极限值205 0x27c 0x775 140ppm
|
||||
fpgaComm->setDpi(config.g200params.dpi); // 0 300dpi 1 200dpi
|
||||
fpgaComm->setSample(256);
|
||||
fpgaComm->enableLed(true);
|
||||
// 设置曝光值等
|
||||
|
||||
configFPGAParam(false, config.g200params.color);
|
||||
|
||||
// fpgaComm->setFrameHeight(12);
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
// fpgaComm->capture();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
video->open(1632, config.g200params.color ? height : height / 3);
|
||||
fpgaComm->setFrameHeight(12);
|
||||
for (int i = 0; i < 1; i++)
|
||||
{
|
||||
fpgaComm->capture();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
fpgaComm->setFrameHeight(config.g200params.color ? height : height / 3);
|
||||
// fpgaComm->update();
|
||||
}
|
||||
|
||||
void Capturer::close()
|
||||
{
|
||||
if (video)
|
||||
{
|
||||
video->close();
|
||||
}
|
||||
}
|
||||
void Capturer::start()
|
||||
{
|
||||
if (video)
|
||||
video->start();
|
||||
}
|
||||
|
||||
void Capturer::stop()
|
||||
{
|
||||
if (video)
|
||||
video->stop();
|
||||
}
|
||||
|
||||
void Capturer::reset()
|
||||
{
|
||||
fpga_reset();
|
||||
fpgaComm->resetADC();
|
||||
fpgaComm->setDelayTime(0X3e8);
|
||||
fpgaComm->setRegs(0x00, fpgaComm->getRegs(0x00));
|
||||
fpgaComm->setRegs(0x01, fpgaComm->getRegs(0x01));
|
||||
}
|
||||
|
||||
void Capturer::set_size(int width, int height)
|
||||
{
|
||||
if (video)
|
||||
video->set_size(width, height);
|
||||
}
|
||||
|
||||
void Capturer::snap()
|
||||
{
|
||||
fpgaComm->capture();
|
||||
}
|
||||
|
||||
std::shared_ptr<IRegsAccess> Capturer::regs()
|
||||
{
|
||||
return fpgaComm;
|
||||
}
|
||||
|
||||
void Capturer::fpga_reset()
|
||||
{
|
||||
reset_pin->setValue(Gpio::Low);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
reset_pin->setValue(Gpio::High);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
}
|
||||
|
||||
void Capturer::fpga_reload()
|
||||
{
|
||||
// fpga 代码重载
|
||||
fpgaLoad->setValue(Gpio::Low);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaLoad->setValue(Gpio::High);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaComm->resetADC();
|
||||
}
|
||||
|
||||
void Capturer::set_expo(int ix, int val)
|
||||
{
|
||||
switch (ix)
|
||||
{
|
||||
case 0:
|
||||
fpgaComm->setAExposureB(val);
|
||||
break;
|
||||
case 1:
|
||||
fpgaComm->setAExposureG(val); //!< ok
|
||||
break;
|
||||
case 2:
|
||||
fpgaComm->setAExposureR(val); //!< ok
|
||||
break;
|
||||
case 3:
|
||||
fpgaComm->setBExposureB(val);
|
||||
break;
|
||||
case 4:
|
||||
fpgaComm->setBExposureG(val);
|
||||
break;
|
||||
case 5:
|
||||
fpgaComm->setBExposureR(val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
void Capturer::set_gain(int ix, int val)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (ix)
|
||||
fpgaComm->setAGain(i, val);
|
||||
else
|
||||
fpgaComm->setBGain(i, val);
|
||||
}
|
||||
}
|
||||
|
||||
void Capturer::set_offset(int ix, int val)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (ix)
|
||||
fpgaComm->setAOffset(i, val);
|
||||
else
|
||||
fpgaComm->setBOffset(i, val);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
void Capturer::configFPGAParam(bool iscorrect, int mode)
|
||||
{
|
||||
int exposures[2][3];
|
||||
int gains[2][6];
|
||||
int offsets[2][6];
|
||||
if (iscorrect)
|
||||
{
|
||||
memcpy(&exposures[0][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.expF : cisconfigs.grayCorrect.expF, sizeof(int) * 3);
|
||||
memcpy(&exposures[1][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.expB : cisconfigs.grayCorrect.expB, sizeof(int) * 3);
|
||||
memcpy(&gains[0][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.gainF : cisconfigs.grayCorrect.gainF, sizeof(int) * 6);
|
||||
memcpy(&gains[1][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.gainB : cisconfigs.grayCorrect.gainB, sizeof(int) * 6);
|
||||
memcpy(&offsets[0][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.offsetsF : cisconfigs.grayCorrect.offsetsF, sizeof(int) * 6);
|
||||
memcpy(&offsets[1][0], mode == IMAGE_COLOR ? cisconfigs.colorCorrect.offsetsB : cisconfigs.grayCorrect.offsetsB, sizeof(int) * 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&exposures[0][0], mode == IMAGE_COLOR ? cisconfigs.color.expF : cisconfigs.gray.expF, sizeof(int) * 3);
|
||||
memcpy(&exposures[1][0], mode == IMAGE_COLOR ? cisconfigs.color.expB : cisconfigs.gray.expB, sizeof(int) * 3);
|
||||
memcpy(&gains[0][0], mode == IMAGE_COLOR ? cisconfigs.color.gainF : cisconfigs.gray.gainF, sizeof(int) * 6);
|
||||
memcpy(&gains[1][0], mode == IMAGE_COLOR ? cisconfigs.color.gainB : cisconfigs.gray.gainB, sizeof(int) * 6);
|
||||
memcpy(&offsets[0][0], mode == IMAGE_COLOR ? cisconfigs.color.offsetsF : cisconfigs.gray.offsetsF, sizeof(int) * 6);
|
||||
memcpy(&offsets[1][0], mode == IMAGE_COLOR ? cisconfigs.color.offsetsB : cisconfigs.gray.offsetsB, sizeof(int) * 6);
|
||||
}
|
||||
|
||||
// static int val = 0;
|
||||
|
||||
// int step = 100;
|
||||
|
||||
// for(int i = 0;i<2;i++)
|
||||
// {
|
||||
// for(int j =0 ;j<3;j++)
|
||||
// {
|
||||
|
||||
// exposures[i][j] =i==0? cisconfigs.gray.expF[j]*exp_ratio:cisconfigs.gray.expB[j]*exp_ratio;
|
||||
// printf("exp_ratio = %0.2f \r\n",exp_ratio);
|
||||
// }
|
||||
// }
|
||||
// val+=step;
|
||||
// exp_ratio += 0.1;
|
||||
|
||||
// for (int i = 0; i < 2; i++)
|
||||
// {
|
||||
// for (int j = 0; j < 6; j++)
|
||||
// {
|
||||
|
||||
// printf("gains[%d][%d] = %d \r\n", i, j, gains[i][j]);
|
||||
// printf("offsets[%d][%d] = %d \r\n", i, j, offsets[i][j]);
|
||||
// if (j < 3)
|
||||
// {
|
||||
// printf("exposures[%d][%d] = %d \r\n", i, j, exposures[i][j]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
setFGPAParmas(exposures, gains, offsets);
|
||||
}
|
||||
void Capturer::setFGPAParmas(int exposures[2][3], int gains[2][6], int offsets[2][6])
|
||||
{
|
||||
// set exposuretime
|
||||
fpgaComm->setAExposureB(exposures[0][0]);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaComm->setAExposureG(exposures[0][1]);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaComm->setAExposureR(exposures[0][2]);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaComm->setBExposureB(exposures[1][0]);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaComm->setBExposureG(exposures[1][1]);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaComm->setBExposureR(exposures[1][2]);
|
||||
// set Gain and offset
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
// LOGD("setAGain %d =:%d", i , gains[0][i]);
|
||||
fpgaComm->setAGain(i, gains[0][i]); // A面增加
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaComm->setBGain(i, gains[1][i]); // B面增益
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaComm->setAOffset(i, offsets[0][i]); // A面偏置
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
||||
fpgaComm->setBOffset(i, offsets[1][i]); // B面偏置
|
||||
}
|
||||
}
|
||||
|
||||
void *Capturer::readFrame(int timeout)
|
||||
{
|
||||
auto ret = video->read_frame(timeout);
|
||||
unsigned int val;
|
||||
// fpgaComm->update();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Capturer::is_runing()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int Capturer::color()
|
||||
{
|
||||
return fpgaComm->getColorMode() ? 16 : 0;
|
||||
}
|
||||
|
||||
int Capturer::height()
|
||||
{
|
||||
return fpgaComm->getFrameHeight();
|
||||
}
|
||||
|
||||
int Capturer::width()
|
||||
{
|
||||
return 1632;
|
||||
}
|
||||
|
||||
void Capturer::set_sp(int sp)
|
||||
{
|
||||
fpgaComm->setSp(sp);
|
||||
}
|
||||
|
||||
void Capturer::init_autocorrect(int colormode)
|
||||
{
|
||||
std::thread t_correctthread = std::thread(&Capturer::autocorrect, this, colormode);
|
||||
t_correctthread.detach();
|
||||
}
|
||||
|
||||
void Capturer::autocorrect(int colormode)
|
||||
{
|
||||
bcorrecting = true;
|
||||
cisconfigs = getcisparams();
|
||||
scannerinfo = getscannerinfo();
|
||||
ft.clear();
|
||||
ft.append_log("start correct");
|
||||
if (m_captureCallback)
|
||||
{
|
||||
m_captureCallback(colormode, colormode ? "------开始彩色校正------\r\n" : "------开始灰度校正------\r\n");
|
||||
}
|
||||
creatcorrectconfig(colormode ? IMAGE_COLOR : IMAGE_GRAY);
|
||||
creatLUTData(colormode ? IMAGE_COLOR : IMAGE_GRAY, CISVendor::HUALIN_CIS_V0);
|
||||
if (colormode)
|
||||
{
|
||||
memcpy(cisconfigs.color.offsetsF, cisconfigs.colorCorrect.offsetsF, sizeof(int) * 6);
|
||||
memcpy(cisconfigs.color.offsetsB, cisconfigs.colorCorrect.offsetsB, sizeof(int) * 6);
|
||||
memcpy(cisconfigs.color.expF, cisconfigs.colorCorrect.expF, sizeof(int) * 3);
|
||||
memcpy(cisconfigs.color.expB, cisconfigs.colorCorrect.expB, sizeof(int) * 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(cisconfigs.gray.offsetsF, cisconfigs.grayCorrect.offsetsF, sizeof(int) * 6);
|
||||
memcpy(cisconfigs.gray.offsetsB, cisconfigs.grayCorrect.offsetsB, sizeof(int) * 6);
|
||||
memcpy(cisconfigs.gray.expF, cisconfigs.grayCorrect.expF, sizeof(int) * 3);
|
||||
memcpy(cisconfigs.gray.expB, cisconfigs.grayCorrect.expB, sizeof(int) * 3);
|
||||
}
|
||||
savecisparams(cisconfigs);
|
||||
initLut();
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(4, colormode ? "------彩色校正完成------\r\n" : "------灰度校正完成------\r\n");
|
||||
reset();
|
||||
bcorrecting = false;
|
||||
printf("init_autocorrect exit \n");
|
||||
}
|
||||
|
||||
void Capturer::creatcorrectconfig(int mode)
|
||||
{
|
||||
std::string msg = mode == IMAGE_COLOR ? "彩色" : "灰度";
|
||||
// LOG_TRACE("creatcorrectconfig \r\n");
|
||||
ft.append_log("开始" + msg + "暗场校正");
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(mode, "开始" + msg + "暗场校正\r\n");
|
||||
openDevice(mode);
|
||||
bool isDone = false;
|
||||
int i = 1;
|
||||
initStep();
|
||||
while (!isDone) // 先暗场
|
||||
{
|
||||
configFPGAParam(true, mode);
|
||||
string log = "==============================第" + to_string(i) + "次=============================== \r\n";
|
||||
ft.append_log(log);
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(mode, log);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
fpgaComm->enableLed(false);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
// fpgaComm->update();
|
||||
fpgaComm->capture();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
isDone = saveLutImg(mode, mode == IMAGE_COLOR ? 0 : 2); // 0 color_black 1 color_white 2 gray_balck 3 gray_white
|
||||
i++;
|
||||
}
|
||||
i = 1;
|
||||
isDone = false;
|
||||
initStep();
|
||||
ft.append_log("开始" + msg + "明场校正");
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(mode, "开始" + msg + "明场校正 \r\n");
|
||||
while (!isDone) // 后明场
|
||||
{
|
||||
configFPGAParam(true, mode);
|
||||
string log = "==============================第" + to_string(i) + "次=============================== \r\n";
|
||||
ft.append_log(log);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
fpgaComm->enableLed(true);
|
||||
// fpgaComm->update();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
fpgaComm->capture();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
isDone = saveLutImg(mode, mode == IMAGE_COLOR ? 1 : 3);
|
||||
// isDone = true;
|
||||
i++;
|
||||
}
|
||||
LOG_TRACE(string_format("creatcorrectconfig %s \r\n", (mode == IMAGE_COLOR ? " Color" : " Gray")));
|
||||
video->close();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
}
|
||||
|
||||
void Capturer::openDevice(int mode)
|
||||
{
|
||||
this->reset();
|
||||
// #ifdef G00
|
||||
int width = 1632;
|
||||
int height = 6000;
|
||||
// #else
|
||||
// int width = 1728;
|
||||
// int height = 6000;
|
||||
// #endif
|
||||
video->open(width, mode == IMAGE_COLOR ? height : height / 3);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
fpgaComm->capture();
|
||||
video->read_frame(200); // 丢弃第一张无效图像
|
||||
LOG_TRACE(string_format("cisconfigs.grayCorrect.sp = %d \r\n", cisconfigs.grayCorrect.sp));
|
||||
// fpgaComm->setSp(mode == IMAGE_COLOR ? cisconfigs.colorCorrect.sp : cisconfigs.grayCorrect.sp);
|
||||
auto info = getscannerinfo();
|
||||
fpgaComm->setSp(mode == IMAGE_COLOR ? info.color_sp : info.gray_sp); // 0x438 : 0xca8
|
||||
fpgaComm->setSample(256);
|
||||
fpgaComm->setDpi(1);
|
||||
fpgaComm->setColorMode(mode == IMAGE_COLOR ? 1 : 0);
|
||||
fpgaComm->setFrameHeight(mode == IMAGE_COLOR ? height : height / 3);
|
||||
fpgaComm->enableLed(true);
|
||||
}
|
||||
|
||||
static int savelutindex = 0;
|
||||
bool Capturer::saveLutImg(int mode, int index)
|
||||
{
|
||||
int offset_indexs[12] = {0, 1, 2, 5, 4, 3, 3, 4, 5, 2, 1, 0};
|
||||
int count = 1;
|
||||
int height = 6000;
|
||||
int width = 1632;
|
||||
bool isNeedSave = true;
|
||||
string log;
|
||||
for (int i = 0; i < 1; i++)
|
||||
{
|
||||
void *data = video->read_frame(1500);
|
||||
if (data == NULL)
|
||||
{
|
||||
log = "图像采集失败!\r\n";
|
||||
ft.append_log(log);
|
||||
isNeedSave = false;
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(mode, log);
|
||||
}
|
||||
if (data && isNeedSave)
|
||||
{
|
||||
if (mode == IMAGE_COLOR)
|
||||
{
|
||||
cv::Mat mergeMat = GetMergeMat(data, this->width(), this->height(), this->color());
|
||||
cv::cvtColor(mergeMat, mergeMat, CV_RGB2BGR);
|
||||
if (i == 0)
|
||||
{
|
||||
double values[2][3];
|
||||
cv::Scalar a = cv::mean(mergeMat(cv::Rect(0, 0, mergeMat.cols / 2, mergeMat.rows)));
|
||||
cv::Scalar b = cv::mean(mergeMat(cv::Rect(mergeMat.cols / 2, 0, mergeMat.cols / 2, mergeMat.rows)));
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
values[0][j] = a.val[2 - j];
|
||||
values[1][j] = b.val[2 - j];
|
||||
}
|
||||
double offValues[12];
|
||||
for (int n = 0; n < 2; n++)
|
||||
{
|
||||
cv::Mat img = mergeMat(cv::Rect(mergeMat.cols * n / 2, 0, mergeMat.cols / 2, mergeMat.rows));
|
||||
int offset_total = 0;
|
||||
for (int s = 0; s < 6; s++) //
|
||||
{
|
||||
int k = n * 6 + s;
|
||||
int offset_wdth;
|
||||
if ((s == 0 && k == 0) || (s == 5 && k == 11))
|
||||
offset_wdth = 288;
|
||||
else
|
||||
offset_wdth = 432;
|
||||
|
||||
cv::Scalar mean;
|
||||
mean = cv::mean(img(cv::Rect(offset_total, 0, offset_wdth, img.rows)));
|
||||
if ((s == 0 && k == 0) || (s == 5 && k == 11))
|
||||
offset_total += 288;
|
||||
else
|
||||
offset_total += 432;
|
||||
offValues[k] = mean.val[0];
|
||||
}
|
||||
}
|
||||
|
||||
log += " 彩色A面RGB值:" + std::to_string(values[0][0]) + "," + std::to_string(values[0][1]) + "," + std::to_string(values[0][2]) + "\r\n";
|
||||
log += " 彩色B面RGB值:" + std::to_string(values[1][0]) + "," + std::to_string(values[1][1]) + "," + std::to_string(values[1][2]) + "\r\n";
|
||||
ft.append_log(log);
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(mode, log);
|
||||
if (index % 2 == 1)
|
||||
{ // 明场
|
||||
// imwrite(std::to_string(savelutindex++) + "clwh.jpg", mergeMat);
|
||||
log = "开始彩色明场校正 \r\n";
|
||||
for (int s = 0; s < 2; s++)
|
||||
{
|
||||
int *exposures = (int *)(s == 0 ? cisconfigs.colorCorrect.expF : cisconfigs.colorCorrect.expB);
|
||||
for (int x = 0; x < 3; x++)
|
||||
{
|
||||
int k = (3 * s + x);
|
||||
int diff = LIGHT_DIFF(scannerinfo.clr_maxbright, *((double *)values + k));
|
||||
log += " 明场:" + std::to_string(k) + ";diff:" + std::to_string(diff) + "\r\n";
|
||||
|
||||
double step = diff * Radio;
|
||||
int preStep = *((int *)expStep + k);
|
||||
if (step * preStep < 0)
|
||||
{
|
||||
step = 0 - preStep / 2;
|
||||
}
|
||||
FMT_STEP(step);
|
||||
bool isMinStep = abs(step) == 1 && step == *((int *)expStep + k);
|
||||
bool isOutBounds = exposures[x] >= 1770 && step > 0;
|
||||
isOutBounds |= exposures[x] <= 0 && step < 0;
|
||||
if (isOutBounds)
|
||||
log += " 第" + to_string(x) + "个明场校正异常 \r\n";
|
||||
else if (abs(diff) >= 1 || isMinStep)
|
||||
{
|
||||
*((int *)expStep + k) = (int)(step);
|
||||
exposures[x] += step;
|
||||
if (exposures[x] > 1770)
|
||||
{
|
||||
exposures[x] = 1770;
|
||||
}
|
||||
if (exposures[x] < 0)
|
||||
exposures[x] = 0;
|
||||
isNeedSave = false;
|
||||
}
|
||||
log += " 曝光值:" + to_string(exposures[x]) + "\r\n";
|
||||
log += " 调整步长:" + to_string(*((int *)expStep + k)) + "\r\n";
|
||||
if (isNeedSave)
|
||||
log += "彩色明场校正完成\r\n";
|
||||
}
|
||||
}
|
||||
ft.append_log(log);
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(mode, log);
|
||||
}
|
||||
else // 彩色暗场
|
||||
{
|
||||
int *offsets;
|
||||
// imwrite(std::to_string(savelutindex++) + "clrblk.jpg", mergeMat);
|
||||
log = "开始彩色暗场校正";
|
||||
for (int s = 0; s < 2; s++)
|
||||
{
|
||||
offsets = (int *)(s == 0 ? cisconfigs.colorCorrect.offsetsF : cisconfigs.colorCorrect.offsetsB);
|
||||
for (int j = 0; j < 6; j++)
|
||||
{
|
||||
int k = s * 6 + j;
|
||||
double diff = BLACK_DIFF(offValues[k]);
|
||||
double step = Radio * diff;
|
||||
int preStep = offsetStep[k];
|
||||
if (step * preStep < 0)
|
||||
{
|
||||
step = 0 - preStep / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Radio = 1;
|
||||
}
|
||||
FMT_STEP(step);
|
||||
bool isMinStep = abs(step) == 1 && step == offsetStep[k];
|
||||
bool isOutBounds = offsets[j] >= 255 && step > 0;
|
||||
isOutBounds |= offsets[j] <= 0 && step < 0;
|
||||
log += " 暗场校正 :" + std::to_string(k) + ";diff:" + std::to_string(diff) + ";light:" + std::to_string(offValues[k]) + ";offset:" + std::to_string(offsets[j]) + ";step:" + std::to_string(step) + "\r\n";
|
||||
if (isOutBounds)
|
||||
log += " 第" + std::to_string(k) + "条带暗场校正异常,暗场值无法降低 \r\n";
|
||||
else if (abs(step) > 1 || isMinStep)
|
||||
{
|
||||
offsetStep[k] = (int)(step);
|
||||
offsets[offset_indexs[k]] += step;
|
||||
log += "offsetStep" + std::to_string(k) + " = " + std::to_string(offsetStep[k]) + ", offset_indexs" + std::to_string(k) + " =" + std::to_string(offset_indexs[k]) + "\r\n";
|
||||
|
||||
if (offsets[offset_indexs[k]] < 1)
|
||||
offsets[offset_indexs[k]] = 1;
|
||||
if (offsets[offset_indexs[k]] > 255)
|
||||
offsets[offset_indexs[k]] = 255;
|
||||
isNeedSave = false;
|
||||
}
|
||||
log += (s == 0 ? "彩色正面" : "彩色背面");
|
||||
log += "偏移值:" + std::to_string(offsets[0]) + "," + std::to_string(offsets[1]) + "," + std::to_string(offsets[2]) + "," + std::to_string(offsets[3]) + "," + std::to_string(offsets[4]) + "," + std::to_string(offsets[5]) + "\r\n";
|
||||
|
||||
if (isNeedSave)
|
||||
log += (s == 0 ? "彩色正面暗场校正完成 \r\n" : "彩色背面暗场校正完成 \r\n");
|
||||
}
|
||||
}
|
||||
ft.append_log(log);
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(mode, log);
|
||||
}
|
||||
if (isNeedSave)
|
||||
{
|
||||
mBuffMat.release();
|
||||
mBuffMat = mergeMat;
|
||||
}
|
||||
}
|
||||
if (isNeedSave && i == 0)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
out.release();
|
||||
cv::vconcat(mBuffMat, mergeMat, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
mergeMat.copyTo(out);
|
||||
cv::cvtColor(out, out, CV_BGR2RGB);
|
||||
}
|
||||
char buffer[40];
|
||||
sprintf(buffer, "/usr/local/huago/lut_%d.bmp", index);
|
||||
imwrite(buffer, out);
|
||||
LOG_TRACE(string_format("save image %s ", buffer));
|
||||
}
|
||||
else if (i != 0)
|
||||
{
|
||||
cv::vconcat(mBuffMat, mergeMat, mBuffMat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // 灰色模式
|
||||
cv::Mat src = GetMergeMat(data, this->width(), this->height(), this->color());
|
||||
// imwrite(std::to_string(savelutindex++) + "graywh.jpg", src);
|
||||
char buffer[40];
|
||||
sprintf(buffer, "/usr/local/huago/lut_%d.bmp", index);
|
||||
double values[2];
|
||||
values[0] = cv::mean(src(cv::Rect(0, 0, src.cols / 2, src.rows))).val[0];
|
||||
values[1] = cv::mean(src(cv::Rect(src.cols / 2, 0, src.cols / 2, src.rows))).val[0];
|
||||
|
||||
double offValues[12];
|
||||
for (int n = 0; n < 2; n++)
|
||||
{
|
||||
cv::Mat img = src(cv::Rect(src.cols * n / 2, 0, src.cols / 2, src.rows));
|
||||
int offset_total = 0;
|
||||
for (int s = 0; s < 6; s++) //
|
||||
{
|
||||
int k = n * 6 + s;
|
||||
int offset_wdth;
|
||||
if ((s == 0 && k == 0) || (s == 5 && k == 11))
|
||||
offset_wdth = 288;
|
||||
else
|
||||
offset_wdth = 432;
|
||||
|
||||
cv::Scalar mean;
|
||||
mean = cv::mean(img(cv::Rect(offset_total, 0, offset_wdth, img.rows)));
|
||||
if ((s == 0 && k == 0) || (s == 5 && k == 11))
|
||||
offset_total += 288;
|
||||
else
|
||||
offset_total += 432;
|
||||
offValues[k] = mean.val[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (index % 2 == 1) // 灰度明场
|
||||
{
|
||||
log = "-----开始灰色明场校正-----\r\n";
|
||||
log += " 灰色扫描灰度明场均值:" + to_string(values[0]) + "," + to_string(values[1]) + "\r\n";
|
||||
for (int s = 0; s < 2; s++)
|
||||
{
|
||||
int *exposures = (int *)(s == 0 ? cisconfigs.grayCorrect.expF : cisconfigs.grayCorrect.expB);
|
||||
int diff = LIGHT_DIFF(scannerinfo.gray_maxbright, values[s]);
|
||||
double step = diff * Radio;
|
||||
log += " 明场:" + to_string(s) + ";diff:" + to_string(diff) + "\r\n";
|
||||
int preStep = expStep[s][0];
|
||||
if (step * preStep < 0)
|
||||
{
|
||||
step = 0 - preStep / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Radio = 1;
|
||||
}
|
||||
FMT_STEP(step);
|
||||
|
||||
int exp = *(exposures + 1);
|
||||
std::string ss1(string_format("exp[%d] = %d step = %.3f \r\n", s, exp, step));
|
||||
log += ss1;
|
||||
bool isMinStep = abs(step) == 1 && step == expStep[s][0];
|
||||
bool isOutBounds = exp >= 1770 && step > 0;
|
||||
isOutBounds |= exp <= 0 && step < 0;
|
||||
if (isOutBounds)
|
||||
log += " 第" + to_string(s) + "个明场校正异常 \r\n";
|
||||
else if (abs(diff) > 1 || isMinStep)
|
||||
{
|
||||
exp += step;
|
||||
if (exp < 0)
|
||||
exp = 0;
|
||||
if (exp > 1770)
|
||||
exp = 1770;
|
||||
|
||||
float coffe[3] = {1, 1, 1}; // 0.2, 1,0.51
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
*(exposures + k) = (int)(exp * coffe[k]);
|
||||
expStep[s][k] = (int)(step);
|
||||
std::string exps(string_format("expStep[%d][%d] = %.3f\r\n", s, k, step));
|
||||
log += exps;
|
||||
std::string ss(string_format("exposures[%d] = %0.3f \r\n", k, exposures[k]));
|
||||
log += ss;
|
||||
}
|
||||
isNeedSave = false;
|
||||
}
|
||||
}
|
||||
ft.append_log(log);
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(mode, log);
|
||||
}
|
||||
else // 灰度暗场
|
||||
{
|
||||
log = "开始灰色暗场校正 \r\n";
|
||||
for (int s = 0; s < 2; s++)
|
||||
{
|
||||
int *offsets = (int *)(s == 0 ? cisconfigs.grayCorrect.offsetsF : cisconfigs.grayCorrect.offsetsB);
|
||||
for (int j = 0; j < 6; j++)
|
||||
{
|
||||
int k = s * 6 + j;
|
||||
double diff = BLACK_DIFF(offValues[k]);
|
||||
double step = Radio * diff;
|
||||
int preStep = offsetStep[k];
|
||||
if (step * preStep < 0)
|
||||
{
|
||||
step = 0 - preStep / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Radio = 1;
|
||||
}
|
||||
FMT_STEP(step);
|
||||
bool isMinStep = abs(step) == 1 && step == offsetStep[k];
|
||||
bool isOutBounds = offsets[j] >= 255 && step > 0;
|
||||
isOutBounds |= offsets[j] <= 0 && step < 0;
|
||||
log += " 暗场校正 :" + std::to_string(k) + ";diff:" + std::to_string(diff) + ";light:" + std::to_string(offValues[k]) + ";offset:" + std::to_string(offsets[j]) + ";step:" + std::to_string(step) + "\r\n";
|
||||
if (isOutBounds)
|
||||
log += " 第" + std::to_string(i) + "面暗场校正异常,暗场值无法降低 \r\n";
|
||||
else if (abs(step) > 1 || isMinStep)
|
||||
{
|
||||
offsetStep[k] = (int)(step);
|
||||
offsets[offset_indexs[k]] += step;
|
||||
log += "offsetStep" + std::to_string(k) + " = " + std::to_string(offsetStep[k]) + ", offset_indexs" + std::to_string(k) + " =" + std::to_string(offset_indexs[k]) + "\r\n";
|
||||
|
||||
if (offsets[offset_indexs[k]] < 1)
|
||||
offsets[offset_indexs[k]] = 1;
|
||||
if (offsets[offset_indexs[k]] > 255)
|
||||
offsets[offset_indexs[k]] = 255;
|
||||
isNeedSave = false;
|
||||
}
|
||||
}
|
||||
log += " 灰度偏移值:" + std::to_string(offsets[0]) + "," + std::to_string(offsets[1]) + "," + std::to_string(offsets[2]) + "," + std::to_string(offsets[3]) + "," + std::to_string(offsets[4]) + "," + std::to_string(offsets[5]) + "\r\n";
|
||||
|
||||
if (isNeedSave)
|
||||
log += "灰色暗场校正完成 \r\n";
|
||||
}
|
||||
// final report
|
||||
ft.append_log(log);
|
||||
if (m_captureCallback)
|
||||
m_captureCallback(mode, log);
|
||||
}
|
||||
if (isNeedSave)
|
||||
{
|
||||
LOG_TRACE(string_format("save image path %s", buffer));
|
||||
imwrite(buffer, src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isNeedSave;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
#include <ICapturer.h>
|
||||
#include "hgutils.h"
|
||||
|
||||
class FpgaComm;
|
||||
class gVideo;
|
||||
class Gpio;
|
||||
|
||||
class Capturer : public ICapturer
|
||||
{
|
||||
public:
|
||||
Capturer();
|
||||
virtual ~Capturer();
|
||||
virtual void Fpga_regsAccess_reset(bool enable);
|
||||
virtual void open();
|
||||
virtual void open(HGScanConfig config, FPGAConfigParam fpgaparam);
|
||||
virtual void close();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool is_runing();
|
||||
virtual void snap();
|
||||
virtual void stopsnap() {}
|
||||
virtual int getautosizeheight() { return 0; }
|
||||
virtual void set_size(int width, int height);
|
||||
virtual void set_sp(int sp);
|
||||
|
||||
virtual void *readFrame(int timeout);
|
||||
|
||||
virtual void set_gain(int ix, int val);
|
||||
virtual void set_offset(int ix, int val);
|
||||
virtual void set_expo(int ix, int val);
|
||||
|
||||
virtual std::shared_ptr<IRegsAccess> regs();
|
||||
virtual void reset();
|
||||
virtual int width();
|
||||
virtual int height();
|
||||
virtual int color();
|
||||
virtual void init_autocorrect(int colormode);
|
||||
virtual void setcapturecall(std::function<void(int, std::string)> callback)
|
||||
{
|
||||
m_captureCallback = callback;
|
||||
};
|
||||
virtual void single_correct(std::uint32_t mode) override {}
|
||||
|
||||
private:
|
||||
void setFGPAParmas(int exposures[2][3], int gains[2][6], int offsets[2][6]);
|
||||
void configFPGAParam(bool iscorrect, int mode);
|
||||
void fpga_reset();
|
||||
void fpga_reload();
|
||||
void autocorrect(int colormode);
|
||||
void creatcorrect(int mode);
|
||||
void openDevice(int mode);
|
||||
void creatcorrectconfig(int mode);
|
||||
bool saveLutImg(int mode, int index);
|
||||
std::shared_ptr<Gpio> vdd_cis_3voff_pin;
|
||||
std::shared_ptr<Gpio> vdd_vis_5ven_pin;
|
||||
std::shared_ptr<Gpio> reset_pin;
|
||||
std::shared_ptr<Gpio> image_in_transfer_pin;
|
||||
std::shared_ptr<Gpio> initDone_pin;
|
||||
std::shared_ptr<Gpio> fpgaLoad;
|
||||
std::shared_ptr<FpgaComm> fpgaComm;
|
||||
|
||||
std::shared_ptr<gVideo> video;
|
||||
std::function<void(int, std::string)> m_captureCallback;
|
||||
HGScanConfig m_configParam;
|
||||
bool bcorrecting;
|
||||
std::thread m_correctthread;
|
||||
HGCorrectConfigs cisconfigs;
|
||||
ScannerNativeParam scannerinfo;
|
||||
};
|
|
@ -0,0 +1,856 @@
|
|||
#include "CorrectParam.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "commondef.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define JSONPATH "/usr/local/huago/cameraparam.json"
|
||||
#define JSONPATH_8478 "/usr/local/huago/cameraparam_8478.json"
|
||||
#define JSONPATH_8458_COLOR_LVDS "/usr/local/huago/cameraparam_8458_color_lvds.json"
|
||||
#define JSONPATH_8478_HL_LVDS "/usr/local/huago/cameraparam_8478_HL_lvds.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"
|
||||
|
||||
#define LUTslow_moireCOLORPATH "/usr/local/huago/lutslow_moireclr.bmp"
|
||||
#define TEXTLUTslow_moireCOLORPATH "/usr/local/huago/Textlutslow_moireclr.bmp"
|
||||
#define LUTslow_moire_COLOR_BLACKPATH "/usr/local/huago/lutslow_moireclrbw.bmp"
|
||||
#define LUTslow_moire_COLOR_WHITEPATH "/usr/local/huago/lutslow_moireclrwhite.bmp"
|
||||
|
||||
#define LUTslow_moireGRAYPATH "/usr/local/huago/lutslow_moiregray.bmp"
|
||||
#define TEXTLUTslow_moireGRAYPATH "/usr/local/huago/Textlutslow_moiregray.bmp"
|
||||
#define LUTslow_moire_GRAY_BLACKPATH "/usr/local/huago/lutslow_moiregraybw.bmp"
|
||||
#define LUTslow_moire_GRAY_WHITEPATH "/usr/local/huago/lutslow_moiregraywhite.bmp"
|
||||
|
||||
#define LUTslow_moire_300_COLORPATH "/usr/local/huago/lutslow_moire300clr.bmp"
|
||||
#define TEXTLUTslow_moire_300_COLORPATH "/usr/local/huago/Textlutslow_moire300clr.bmp"
|
||||
#define LUTslow_moire_300_COLOR_BLACKPATH "/usr/local/huago/lutslow_moire300clrbw.bmp"
|
||||
#define LUTslow_moire_300_COLOR_WHITEPATH "/usr/local/huago/lutslow_moire300clrwhite.bmp"
|
||||
|
||||
#define LUTslow_moire_300_GRAYPATH "/usr/local/huago/lutslow_moire300gray.bmp"
|
||||
#define TEXTLUTslow_moire_300_GRAYPATH "/usr/local/huago/Textlutslow_moire300gray.bmp"
|
||||
#define LUTslow_moire_300_GRAY_BLACKPATH "/usr/local/huago/lutslow_moire300graybw.bmp"
|
||||
#define LUTslow_moire_300_GRAY_WHITEPATH "/usr/local/huago/lutslow_moire300graywhite.bmp"
|
||||
|
||||
#define LUTLong_Manuscript_200_COLORPATH "/usr/local/huago/lutLong_Manuscript200clr.bmp"
|
||||
#define TEXTLUTLong_Manuscript_200_COLORPATH "/usr/local/huago/TextlutLong_Manuscript200clr.bmp"
|
||||
#define LUTLong_Manuscript_200_COLOR_BLACKPATH "/usr/local/huago/lutLong_Manuscript200clrbw.bmp"
|
||||
#define LUTLong_Manuscript_200_COLOR_WHITEPATH "/usr/local/huago/lutLong_Manuscript200clrwhite.bmp"
|
||||
|
||||
#define LUTLong_Manuscript_200_GRAYPATH "/usr/local/huago/lutLong_Manuscript200gray.bmp"
|
||||
#define TEXTLUTLong_Manuscript_200_GRAYPATH "/usr/local/huago/TextlutLong_Manuscript200gray.bmp"
|
||||
#define LUTLong_Manuscript_200_GRAY_BLACKPATH "/usr/local/huago/lutLong_Manuscript200graybw.bmp"
|
||||
#define LUTLong_Manuscript_200_GRAY_WHITEPATH "/usr/local/huago/lutLong_Manuscript200graywhite.bmp"
|
||||
|
||||
#define LUTLong_Manuscript_300_COLORPATH "/usr/local/huago/lutLong_Manuscript300clr.bmp"
|
||||
#define TEXTLUTLong_Manuscript_300_COLORPATH "/usr/local/huago/TextlutLong_Manuscript300clr.bmp"
|
||||
#define LUTLong_Manuscript_300_COLOR_BLACKPATH "/usr/local/huago/lutLong_Manuscript300clrbw.bmp"
|
||||
#define LUTLong_Manuscript_300_COLOR_WHITEPATH "/usr/local/huago/lutLong_Manuscript300clrwhite.bmp"
|
||||
|
||||
#define LUTLong_Manuscript_300_GRAYPATH "/usr/local/huago/lutLong_Manuscript300gray.bmp"
|
||||
#define TEXTLUTLong_Manuscript_300_GRAYPATH "/usr/local/huago/TextlutLong_Manuscript300gray.bmp"
|
||||
#define LUTLong_Manuscript_300_GRAY_BLACKPATH "/usr/local/huago/lutLong_Manuscript300graybw.bmp"
|
||||
#define LUTLong_Manuscript_300_GRAY_WHITEPATH "/usr/local/huago/lutLong_Manuscript300graywhite.bmp"
|
||||
|
||||
|
||||
CorrectParam::CorrectParam()
|
||||
{
|
||||
initdefaultpapram();
|
||||
}
|
||||
|
||||
CorrectParam::~CorrectParam()
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<FPGAConfigParam> CorrectParam::GetCorrectParams()
|
||||
{
|
||||
std::ifstream i(JSONPATH);
|
||||
json j;
|
||||
i >> j;
|
||||
i.close();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
std::vector<FPGAConfigParam> CorrectParam::GetCorrectParams_8458_Color_Lvds()
|
||||
{
|
||||
std::ifstream i(JSONPATH_8458_COLOR_LVDS);
|
||||
json j;
|
||||
i >> j;
|
||||
i.close();
|
||||
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_8458_color_Lvds(int dpi, int mode){
|
||||
std::lock_guard<std::mutex> lc(m_lock);
|
||||
FPGAConfigParam param;
|
||||
auto filejson = GetCorrectParams_8458_Color_Lvds();
|
||||
bool isfind = false;
|
||||
for (size_t i = 0; i < filejson.size(); i++)
|
||||
{
|
||||
if ((filejson[i].ColorMode == mode) &&
|
||||
(filejson[i].DpiMode == dpi))
|
||||
{
|
||||
param = filejson[i];
|
||||
isfind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
|
||||
FPGAConfigParam CorrectParam::GetFpgaparam(int dpi, int mode)
|
||||
{
|
||||
std::lock_guard<std::mutex> lc(m_lock);
|
||||
FPGAConfigParam param;
|
||||
auto filejson = GetCorrectParams();
|
||||
bool isfind = false;
|
||||
for (size_t i = 0; i < filejson.size(); i++)
|
||||
{
|
||||
if ((filejson[i].ColorMode == mode) &&
|
||||
(filejson[i].DpiMode == dpi))
|
||||
{
|
||||
param = filejson[i];
|
||||
isfind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isfind == false && dpi == 0x10)
|
||||
{
|
||||
FPGAConfigParam nodeparam;
|
||||
json t_j;
|
||||
nodeparam.ColorMode = 1; // 彩色
|
||||
nodeparam.DpiMode = 2; // 300 dpi
|
||||
nodeparam.MaxBright = 200;
|
||||
nodeparam.MaxExp = 1100;
|
||||
nodeparam.HRatio = 1065353216;
|
||||
nodeparam.VRatio = 1065353216;
|
||||
// 慢速摩尔纹 彩色
|
||||
nodeparam.MaxBright = 200;
|
||||
nodeparam.ColorMode = 1; // 彩色
|
||||
nodeparam.DpiMode = 0x10; // 200 dpi
|
||||
nodeparam.LutPath = LUTslow_moireCOLORPATH;
|
||||
nodeparam.TextLutPath = TEXTLUTslow_moireCOLORPATH;
|
||||
nodeparam.Flat_BwPath = LUTslow_moire_COLOR_BLACKPATH;
|
||||
nodeparam.Flat_WhitePath = LUTslow_moire_COLOR_WHITEPATH;
|
||||
#ifdef G100
|
||||
nodeparam.Sp = 875;
|
||||
#else
|
||||
nodeparam.Sp = 878;
|
||||
#endif
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
{
|
||||
if (i < 3)
|
||||
nodeparam.ExposureB[i] = nodeparam.ExposureF[i] = 650; // 1500
|
||||
nodeparam.GainF[i] = nodeparam.GainB[i] = 170;
|
||||
nodeparam.OffsetF[i] = nodeparam.OffsetB[i] = 125;
|
||||
}
|
||||
filejson.push_back(nodeparam);
|
||||
param = nodeparam;
|
||||
// 慢速摩尔纹 灰度
|
||||
nodeparam.MaxBright = 220;
|
||||
nodeparam.ColorMode = 0; // 灰度
|
||||
nodeparam.LutPath = LUTslow_moireGRAYPATH;
|
||||
nodeparam.TextLutPath = TEXTLUTslow_moireGRAYPATH;
|
||||
nodeparam.Flat_BwPath = LUTslow_moire_GRAY_BLACKPATH;
|
||||
nodeparam.Flat_WhitePath = LUTslow_moire_GRAY_WHITEPATH;
|
||||
#ifdef G100
|
||||
nodeparam.Sp = 2626;
|
||||
#else
|
||||
nodeparam.Sp = 2637;
|
||||
#endif
|
||||
filejson.push_back(nodeparam);
|
||||
if (mode == 0)
|
||||
param = nodeparam;
|
||||
json j = json::array();
|
||||
for (size_t i = 0; i < filejson.size(); i++)
|
||||
{
|
||||
json t_j;
|
||||
to_json(t_j, filejson[i]);
|
||||
j.push_back(t_j);
|
||||
}
|
||||
ofstream ofs(JSONPATH);
|
||||
ofs << std::setw(4) << j << std::endl;
|
||||
ofs.close();
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
void CorrectParam::SaveCorrectParam(FPGAConfigParam &parms)
|
||||
{
|
||||
std::lock_guard<std::mutex> lc(m_lock);
|
||||
auto filejson = GetCorrectParams();
|
||||
for (size_t i = 0; i < filejson.size(); i++)
|
||||
{
|
||||
if ((filejson[i].ColorMode == parms.ColorMode) &&
|
||||
(filejson[i].DpiMode == parms.DpiMode))
|
||||
{
|
||||
memcpy(filejson[i].ExposureB, parms.ExposureB, sizeof(parms.ExposureB));
|
||||
memcpy(filejson[i].ExposureF, parms.ExposureF, sizeof(parms.ExposureF));
|
||||
memcpy(filejson[i].GainB, parms.GainB, sizeof(parms.GainB));
|
||||
memcpy(filejson[i].GainF, parms.GainF, sizeof(parms.GainF));
|
||||
memcpy(filejson[i].OffsetB, parms.OffsetB, sizeof(parms.OffsetB));
|
||||
memcpy(filejson[i].OffsetF, parms.OffsetF, sizeof(parms.OffsetF));
|
||||
filejson[i].LutPath = parms.LutPath;
|
||||
filejson[i].TextLutPath = parms.TextLutPath;
|
||||
filejson[i].Flat_BwPath = parms.Flat_BwPath;
|
||||
filejson[i].Flat_WhitePath = parms.Flat_WhitePath;
|
||||
filejson[i].Sp = parms.Sp;
|
||||
filejson[i].HRatio = parms.HRatio;
|
||||
filejson[i].VRatio = parms.VRatio;
|
||||
break;
|
||||
}
|
||||
}
|
||||
json j = json::array();
|
||||
for (size_t i = 0; i < filejson.size(); i++)
|
||||
{
|
||||
json t_j;
|
||||
to_json(t_j, filejson[i]);
|
||||
j.push_back(t_j);
|
||||
}
|
||||
ofstream ofs(JSONPATH);
|
||||
ofs << std::setw(4) << j << std::endl;
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
void CorrectParam::initdefaultpapram()
|
||||
{
|
||||
|
||||
json js = json::array();
|
||||
json js_8478 = json::array();
|
||||
{
|
||||
FPGAConfigParam param;
|
||||
FPGAConfigParam_8478 param_8478;
|
||||
json t_j, t_j_8478;
|
||||
|
||||
// 彩色 300 dpi
|
||||
param_8478.ColorMode = param.ColorMode = 1; // 彩色
|
||||
param_8478.DpiMode = param.DpiMode = 2; // 300 dpi
|
||||
param_8478.MaxBright = param.MaxBright = 200;
|
||||
param_8478.MaxExp = param.MaxExp = 1100;
|
||||
param_8478.HRatio = param.HRatio = 1065353216;
|
||||
param_8478.VRatio = param.VRatio = 1065353216;
|
||||
param_8478.LutPath = param.LutPath = LUT300COLORPATH;
|
||||
param_8478.TextLutPath = param.TextLutPath = TEXTLUT300COLORPATH;
|
||||
param_8478.Flat_BwPath = param.Flat_BwPath = LUT300_COLOR_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = param.Flat_WhitePath = LUT300_COLOR_WHITEPATH;
|
||||
param_8478.Sp = 4680;
|
||||
param.Sp = 1200;
|
||||
for (size_t i = 0; i < 9; i++)
|
||||
{
|
||||
if (i < 6)
|
||||
{
|
||||
if (i < 3)
|
||||
param.ExposureB[i] = param.ExposureF[i] = 700; // 1500
|
||||
param.GainF[i] = param.GainB[i] = 170;
|
||||
param.OffsetF[i] = param.OffsetB[i] = 125;
|
||||
}
|
||||
if (i < 3)
|
||||
param_8478.ExposureB[i] = param_8478.ExposureF[i] = 200; // 1500
|
||||
param_8478.GainF_R[i] = param_8478.GainB_R[i] = param_8478.GainF_G[i] = param_8478.GainB_G[i] =
|
||||
param_8478.GainF_B[i] = param_8478.GainB_B[i] = 80;
|
||||
param_8478.OffsetF_R[i] = param_8478.OffsetB_R[i] = param_8478.OffsetF_G[i] = param_8478.OffsetB_G[i] =
|
||||
param_8478.OffsetF_B[i] = param_8478.OffsetB_B[i] = 180;
|
||||
}
|
||||
to_json(t_j, param);
|
||||
to_json(t_j_8478, param_8478);
|
||||
js.push_back(t_j);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 灰度 300 dpi
|
||||
param_8478.ColorMode = param.ColorMode = 0; // 灰度
|
||||
param_8478.MaxBright = param.MaxBright = 200;
|
||||
param_8478.LutPath = param.LutPath = LUT300GRAYPATH;
|
||||
param_8478.TextLutPath = param.TextLutPath = TEXTLUT300GRAYPATH;
|
||||
param_8478.Flat_BwPath = param.Flat_BwPath = LUT300_GRAY_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = param.Flat_WhitePath = LUT300_GRAY_WHITEPATH;
|
||||
to_json(t_j, param);
|
||||
to_json(t_j_8478, param_8478);
|
||||
js.push_back(t_j);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 彩色 200 dpi
|
||||
param_8478.MaxBright = param.MaxBright = 200;
|
||||
param_8478.ColorMode = param.ColorMode = 1; // 彩色
|
||||
param_8478.DpiMode = param.DpiMode = 1; // 200 dpi
|
||||
param_8478.LutPath = param.LutPath = LUT200COLORPATH;
|
||||
param_8478.TextLutPath = param.TextLutPath = TEXTLUT200COLORPATH;
|
||||
param_8478.Flat_BwPath = param.Flat_BwPath = LUT200_COLOR_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = param.Flat_WhitePath = LUT200_COLOR_WHITEPATH;
|
||||
for (size_t i = 0; i < 9; i++)
|
||||
{
|
||||
if (i < 6)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (i < 3)
|
||||
param_8478.ExposureB[i] = param_8478.ExposureF[i] = 200; // 1500
|
||||
param_8478.GainF_R[i] = param_8478.GainB_R[i] = param_8478.GainF_G[i] = param_8478.GainB_G[i] =
|
||||
param_8478.GainF_B[i] = param_8478.GainB_B[i] = 80;
|
||||
param_8478.OffsetF_R[i] = param_8478.OffsetB_R[i] = param_8478.OffsetF_G[i] = param_8478.OffsetB_G[i] =
|
||||
param_8478.OffsetF_B[i] = param_8478.OffsetB_B[i] = 180;
|
||||
}
|
||||
to_json(t_j, param);
|
||||
to_json(t_j_8478, param_8478);
|
||||
js.push_back(t_j);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 灰度 200dpi
|
||||
param_8478.MaxBright = param.MaxBright = 200;
|
||||
param_8478.ColorMode = param.ColorMode = 0; // 灰度
|
||||
param_8478.LutPath = param.LutPath = LUT200GRAYPATH;
|
||||
param_8478.TextLutPath = param.TextLutPath = TEXTLUT200GRAYPATH;
|
||||
param_8478.Flat_BwPath = param.Flat_BwPath = LUT200_GRAY_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = param.Flat_WhitePath = LUT200_GRAY_WHITEPATH;
|
||||
to_json(t_j, param);
|
||||
to_json(t_j_8478, param_8478);
|
||||
js.push_back(t_j);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 彩色 600 dpi
|
||||
param_8478.MaxBright = param.MaxBright = 200;
|
||||
param_8478.ColorMode = param.ColorMode = 1; // 彩色
|
||||
param_8478.DpiMode = param.DpiMode = 0x03; // 200 dpi
|
||||
param_8478.LutPath = param.LutPath = LUT600COLORPATH;
|
||||
param_8478.TextLutPath = param.TextLutPath = TEXTLUT600COLORPATH;
|
||||
param_8478.Flat_BwPath = param.Flat_BwPath = LUT600_COLOR_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = param.Flat_WhitePath = LUT600_COLOR_WHITEPATH;
|
||||
param_8478.Sp = 9000;
|
||||
param.Sp = 3000;
|
||||
for (size_t i = 0; i < 9; i++)
|
||||
{
|
||||
if (i < 6)
|
||||
{
|
||||
if (i < 3)
|
||||
param.ExposureB[i] = param.ExposureF[i] = 1350; // 1500
|
||||
param.GainF[i] = param.GainB[i] = 170;
|
||||
param.OffsetF[i] = param.OffsetB[i] = 125;
|
||||
}
|
||||
if (i < 3)
|
||||
param_8478.ExposureB[i] = param_8478.ExposureF[i] = 200; // 1500
|
||||
param_8478.GainF_R[i] = param_8478.GainB_R[i] = param_8478.GainF_G[i] = param_8478.GainB_G[i] =
|
||||
param_8478.GainF_B[i] = param_8478.GainB_B[i] = 80;
|
||||
param_8478.OffsetF_R[i] = param_8478.OffsetB_R[i] = param_8478.OffsetF_G[i] = param_8478.OffsetB_G[i] =
|
||||
param_8478.OffsetF_B[i] = param_8478.OffsetB_B[i] = 180;
|
||||
}
|
||||
to_json(t_j, param);
|
||||
to_json(t_j_8478, param_8478);
|
||||
js.push_back(t_j);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 灰度 600dpi
|
||||
param_8478.MaxBright = param.MaxBright = 200;
|
||||
param_8478.ColorMode = param.ColorMode = 0; // 灰度
|
||||
param_8478.LutPath = param.LutPath = LUT600GRAYPATH;
|
||||
param_8478.TextLutPath = param.TextLutPath = TEXTLUT600GRAYPATH;
|
||||
param_8478.Flat_BwPath = param.Flat_BwPath = LUT600_GRAY_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = param.Flat_WhitePath = LUT600_GRAY_WHITEPATH;
|
||||
to_json(t_j, param);
|
||||
to_json(t_j_8478, param_8478);
|
||||
js.push_back(t_j);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 慢速摩尔纹 彩色
|
||||
param_8478.MaxBright = param.MaxBright = 200;
|
||||
param_8478.ColorMode = param.ColorMode = 1; // 彩色
|
||||
param_8478.DpiMode = param.DpiMode = 0x10; // 200 dpi
|
||||
param_8478.LutPath = param.LutPath = LUTslow_moireCOLORPATH;
|
||||
param_8478.TextLutPath = param.TextLutPath = TEXTLUTslow_moireCOLORPATH;
|
||||
param_8478.Flat_BwPath = param.Flat_BwPath = LUTslow_moire_COLOR_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = param.Flat_WhitePath = LUTslow_moire_COLOR_WHITEPATH;
|
||||
#ifdef G100
|
||||
param_8478.Sp = 4680;
|
||||
param.Sp = 875;
|
||||
#else
|
||||
param_8478.Sp = 4680;
|
||||
param.Sp = 878;
|
||||
#endif
|
||||
for (size_t i = 0; i < 9; i++)
|
||||
{
|
||||
if (i < 6)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (i < 3)
|
||||
param_8478.ExposureB[i] = param_8478.ExposureF[i] = 200; // 1500
|
||||
param_8478.GainF_R[i] = param_8478.GainB_R[i] = param_8478.GainF_G[i] = param_8478.GainB_G[i] =
|
||||
param_8478.GainF_B[i] = param_8478.GainB_B[i] = 80;
|
||||
param_8478.OffsetF_R[i] = param_8478.OffsetB_R[i] = param_8478.OffsetF_G[i] = param_8478.OffsetB_G[i] =
|
||||
param_8478.OffsetF_B[i] = param_8478.OffsetB_B[i] = 180;
|
||||
}
|
||||
to_json(t_j, param);
|
||||
to_json(t_j_8478, param_8478);
|
||||
js.push_back(t_j);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 慢速摩尔纹 灰度
|
||||
param_8478.MaxBright = param.MaxBright = 200;
|
||||
param_8478.ColorMode = param.ColorMode = 0; // 灰度
|
||||
param_8478.LutPath = param.LutPath = LUTslow_moireGRAYPATH;
|
||||
param_8478.TextLutPath = param.TextLutPath = TEXTLUTslow_moireGRAYPATH;
|
||||
param_8478.Flat_BwPath = param.Flat_BwPath = LUTslow_moire_GRAY_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = param.Flat_WhitePath = LUTslow_moire_GRAY_WHITEPATH;
|
||||
#ifdef G100
|
||||
param_8478.Sp = 4680;
|
||||
param.Sp = 2626;
|
||||
#else
|
||||
param_8478.Sp = 4680;
|
||||
param.Sp = 2637;
|
||||
#endif
|
||||
to_json(t_j, param);
|
||||
to_json(t_j_8478, param_8478);
|
||||
js.push_back(t_j);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 慢速摩尔纹 300dpi 彩色
|
||||
param_8478.MaxBright = 200;
|
||||
param_8478.ColorMode = 1; // 彩色
|
||||
param_8478.DpiMode = 0x11; // 200 dpi
|
||||
param_8478.LutPath = LUTslow_moire_300_COLORPATH;
|
||||
param_8478.TextLutPath = TEXTLUTslow_moire_300_COLORPATH;
|
||||
param_8478.Flat_BwPath = LUTslow_moire_300_COLOR_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = LUTslow_moire_300_COLOR_WHITEPATH;
|
||||
#ifdef G100
|
||||
param_8478.Sp = 6460;
|
||||
#else
|
||||
param_8478.Sp = 6460;
|
||||
#endif
|
||||
for (size_t i = 0; i < 9; i++)
|
||||
{
|
||||
if (i < 3)
|
||||
param_8478.ExposureB[i] = param_8478.ExposureF[i] = 200; // 1500
|
||||
param_8478.GainF_R[i] = param_8478.GainB_R[i] = param_8478.GainF_G[i] = param_8478.GainB_G[i] =
|
||||
param_8478.GainF_B[i] = param_8478.GainB_B[i] = 80;
|
||||
param_8478.OffsetF_R[i] = param_8478.OffsetB_R[i] = param_8478.OffsetF_G[i] = param_8478.OffsetB_G[i] =
|
||||
param_8478.OffsetF_B[i] = param_8478.OffsetB_B[i] = 180;
|
||||
}
|
||||
to_json(t_j_8478, param_8478);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 慢速摩尔纹 300dpi 灰度
|
||||
param_8478.MaxBright = 200;
|
||||
param_8478.ColorMode = 0; // 灰度
|
||||
param_8478.LutPath = LUTslow_moire_300_GRAYPATH;
|
||||
param_8478.TextLutPath = TEXTLUTslow_moire_300_GRAYPATH;
|
||||
param_8478.Flat_BwPath = LUTslow_moire_300_GRAY_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = LUTslow_moire_300_GRAY_WHITEPATH;
|
||||
#ifdef G100
|
||||
param_8478.Sp = 6460;
|
||||
#else
|
||||
param_8478.Sp = 6460;
|
||||
#endif
|
||||
to_json(t_j_8478, param_8478);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
|
||||
// 长文稿 200dpi 彩色
|
||||
param_8478.MaxBright = 200;
|
||||
param_8478.ColorMode = 1; // 彩色
|
||||
param_8478.DpiMode = 0x20; // 200 dpi
|
||||
param_8478.LutPath = LUTLong_Manuscript_200_COLORPATH;;
|
||||
param_8478.TextLutPath = TEXTLUTLong_Manuscript_200_COLORPATH;
|
||||
param_8478.Flat_BwPath = LUTLong_Manuscript_200_COLOR_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = LUTLong_Manuscript_200_COLOR_WHITEPATH;
|
||||
#ifdef G100
|
||||
param_8478.Sp = 6460;
|
||||
#else
|
||||
param_8478.Sp = 30627;
|
||||
#endif
|
||||
for (size_t i = 0; i < 9; i++)
|
||||
{
|
||||
if (i < 3)
|
||||
param_8478.ExposureB[i] = param_8478.ExposureF[i] = 200; // 1500
|
||||
param_8478.GainF_R[i] = param_8478.GainB_R[i] = param_8478.GainF_G[i] = param_8478.GainB_G[i] =
|
||||
param_8478.GainF_B[i] = param_8478.GainB_B[i] = 80;
|
||||
param_8478.OffsetF_R[i] = param_8478.OffsetB_R[i] = param_8478.OffsetF_G[i] = param_8478.OffsetB_G[i] =
|
||||
param_8478.OffsetF_B[i] = param_8478.OffsetB_B[i] = 180;
|
||||
}
|
||||
to_json(t_j_8478, param_8478);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 长文稿 200dpi 灰度
|
||||
param_8478.MaxBright = 200;
|
||||
param_8478.ColorMode = 0; // 灰度
|
||||
param_8478.LutPath = LUTLong_Manuscript_200_GRAYPATH;;
|
||||
param_8478.TextLutPath = TEXTLUTLong_Manuscript_200_GRAYPATH;
|
||||
param_8478.Flat_BwPath = LUTLong_Manuscript_200_GRAY_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = LUTLong_Manuscript_200_GRAY_WHITEPATH;
|
||||
#ifdef G100
|
||||
param_8478.Sp = 6460;
|
||||
#else
|
||||
param_8478.Sp = 30627;
|
||||
#endif
|
||||
to_json(t_j_8478, param_8478);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
|
||||
|
||||
// 长文稿 300dpi 彩色
|
||||
param_8478.MaxBright = 200;
|
||||
param_8478.ColorMode = 1; // 彩色
|
||||
param_8478.DpiMode = 0x21; // 200 dpi
|
||||
param_8478.LutPath = LUTLong_Manuscript_300_COLORPATH;;
|
||||
param_8478.TextLutPath = TEXTLUTLong_Manuscript_300_COLORPATH;
|
||||
param_8478.Flat_BwPath = LUTLong_Manuscript_300_COLOR_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = LUTLong_Manuscript_300_COLOR_WHITEPATH;
|
||||
#ifdef G100
|
||||
param_8478.Sp = 6460;
|
||||
#else
|
||||
param_8478.Sp = 20436;
|
||||
#endif
|
||||
for (size_t i = 0; i < 9; i++)
|
||||
{
|
||||
if (i < 3)
|
||||
param_8478.ExposureB[i] = param_8478.ExposureF[i] = 200; // 1500
|
||||
param_8478.GainF_R[i] = param_8478.GainB_R[i] = param_8478.GainF_G[i] = param_8478.GainB_G[i] =
|
||||
param_8478.GainF_B[i] = param_8478.GainB_B[i] = 80;
|
||||
param_8478.OffsetF_R[i] = param_8478.OffsetB_R[i] = param_8478.OffsetF_G[i] = param_8478.OffsetB_G[i] =
|
||||
param_8478.OffsetF_B[i] = param_8478.OffsetB_B[i] = 180;
|
||||
}
|
||||
to_json(t_j_8478, param_8478);
|
||||
js_8478.push_back(t_j_8478);
|
||||
|
||||
// 长文稿 300dpi 灰度
|
||||
param_8478.MaxBright = 200;
|
||||
param_8478.ColorMode = 0; // 灰度
|
||||
param_8478.LutPath = LUTLong_Manuscript_300_GRAYPATH;;
|
||||
param_8478.TextLutPath = TEXTLUTLong_Manuscript_300_GRAYPATH;
|
||||
param_8478.Flat_BwPath = LUTLong_Manuscript_300_GRAY_BLACKPATH;
|
||||
param_8478.Flat_WhitePath = LUTLong_Manuscript_300_GRAY_WHITEPATH;
|
||||
#ifdef G100
|
||||
param_8478.Sp = 6460;
|
||||
#else
|
||||
param_8478.Sp = 20436;
|
||||
#endif
|
||||
to_json(t_j_8478, param_8478);
|
||||
js_8478.push_back(t_j_8478);
|
||||
}
|
||||
|
||||
struct stat buff;
|
||||
if (stat(JSONPATH, &buff) != 0) // 存在
|
||||
{
|
||||
std::ofstream ofs(JSONPATH);
|
||||
ofs << std::setw(4) << js << std::endl;
|
||||
ofs.close();
|
||||
}
|
||||
if (stat(JSONPATH_8478, &buff) != 0) // 存在
|
||||
{
|
||||
std::ofstream ofs(JSONPATH_8478);
|
||||
ofs << std::setw(4) << js_8478 << std::endl;
|
||||
ofs.close();
|
||||
}
|
||||
if (stat(JSONPATH_8458_COLOR_LVDS, &buff) != 0) // 存在
|
||||
{
|
||||
std::ofstream ofs(JSONPATH_8458_COLOR_LVDS);
|
||||
ofs << std::setw(4) << js << std::endl;
|
||||
ofs.close();
|
||||
}
|
||||
if (stat(JSONPATH_8478_HL_LVDS, &buff) != 0) // 存在
|
||||
{
|
||||
std::ofstream ofs(JSONPATH_8478_HL_LVDS);
|
||||
ofs << std::setw(4) << js_8478 << std::endl;
|
||||
ofs.close();
|
||||
}
|
||||
}
|
||||
|
||||
void CorrectParam::to_json(json &j, FPGAConfigParam ¶m)
|
||||
{
|
||||
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 ¶m)
|
||||
{
|
||||
j.at("ExposureF").get_to(param.ExposureF);
|
||||
j.at("GainF").get_to(param.GainF);
|
||||
j.at("OffsetF").get_to(param.OffsetF);
|
||||
j.at("ExposureB").get_to(param.ExposureB);
|
||||
j.at("GainB").get_to(param.GainB);
|
||||
j.at("OffsetB").get_to(param.OffsetB);
|
||||
j.at("DpiMode").get_to(param.DpiMode);
|
||||
j.at("ColorMode").get_to(param.ColorMode);
|
||||
j.at("MaxBright").get_to(param.MaxBright);
|
||||
j.at("MaxExp").get_to(param.MaxExp);
|
||||
j.at("Sp").get_to(param.Sp);
|
||||
j.at("HRatio").get_to(param.HRatio);
|
||||
j.at("VRatio").get_to(param.VRatio);
|
||||
j.at("LutPath").get_to(param.LutPath);
|
||||
j.at("TextLutPath").get_to(param.TextLutPath);
|
||||
j.at("FlatBlackPath").get_to(param.Flat_BwPath);
|
||||
j.at("FlatWhitePath").get_to(param.Flat_WhitePath);
|
||||
}
|
||||
|
||||
std::vector<FPGAConfigParam_8478> CorrectParam::GetCorrectParams_8478()
|
||||
{
|
||||
std::ifstream i(JSONPATH_8478);
|
||||
json j;
|
||||
i >> j;
|
||||
i.close();
|
||||
std::vector<FPGAConfigParam_8478> vct_param;
|
||||
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
||||
{
|
||||
auto tmv = it.value();
|
||||
FPGAConfigParam_8478 param;
|
||||
from_json(tmv, param);
|
||||
vct_param.push_back(param);
|
||||
}
|
||||
return vct_param;
|
||||
}
|
||||
|
||||
std::vector<FPGAConfigParam_8478> CorrectParam::GetCorrectParams_8478_HL_Lvds()
|
||||
{
|
||||
std::ifstream i(JSONPATH_8478_HL_LVDS);
|
||||
json j;
|
||||
i >> j;
|
||||
i.close();
|
||||
std::vector<FPGAConfigParam_8478> vct_param;
|
||||
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
||||
{
|
||||
auto tmv = it.value();
|
||||
FPGAConfigParam_8478 param;
|
||||
from_json(tmv, param);
|
||||
vct_param.push_back(param);
|
||||
}
|
||||
return vct_param;
|
||||
}
|
||||
|
||||
|
||||
void CorrectParam::to_json(json &j, FPGAConfigParam_8478 ¶m)
|
||||
{
|
||||
j = json{{"ExposureF", param.ExposureF},
|
||||
{"GainF_R", param.GainF_R},
|
||||
{"OffsetF_R", param.OffsetF_R},
|
||||
{"GainF_G", param.GainF_G},
|
||||
{"OffsetF_G", param.OffsetF_G},
|
||||
{"GainF_B", param.GainF_B},
|
||||
{"OffsetF_B", param.OffsetF_B},
|
||||
{"ExposureB", param.ExposureB},
|
||||
{"GainB_R", param.GainB_R},
|
||||
{"OffsetB_R", param.OffsetB_R},
|
||||
{"GainB_G", param.GainB_G},
|
||||
{"OffsetB_G", param.OffsetB_G},
|
||||
{"GainB_B", param.GainB_B},
|
||||
{"OffsetB_B", param.OffsetB_B},
|
||||
{"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_8478 ¶m)
|
||||
{
|
||||
j.at("ExposureF").get_to(param.ExposureF);
|
||||
j.at("GainF_R").get_to(param.GainF_R);
|
||||
j.at("OffsetF_R").get_to(param.OffsetF_R);
|
||||
j.at("GainF_G").get_to(param.GainF_G);
|
||||
j.at("OffsetF_G").get_to(param.OffsetF_G);
|
||||
j.at("GainF_B").get_to(param.GainF_B);
|
||||
j.at("OffsetF_B").get_to(param.OffsetF_B);
|
||||
j.at("ExposureB").get_to(param.ExposureB);
|
||||
j.at("GainB_R").get_to(param.GainB_R);
|
||||
j.at("OffsetB_R").get_to(param.OffsetB_R);
|
||||
j.at("GainB_G").get_to(param.GainB_G);
|
||||
j.at("OffsetB_G").get_to(param.OffsetB_G);
|
||||
j.at("GainB_B").get_to(param.GainB_B);
|
||||
j.at("OffsetB_B").get_to(param.OffsetB_B);
|
||||
j.at("DpiMode").get_to(param.DpiMode);
|
||||
j.at("ColorMode").get_to(param.ColorMode);
|
||||
j.at("MaxBright").get_to(param.MaxBright);
|
||||
j.at("MaxExp").get_to(param.MaxExp);
|
||||
j.at("Sp").get_to(param.Sp);
|
||||
j.at("HRatio").get_to(param.HRatio);
|
||||
j.at("VRatio").get_to(param.VRatio);
|
||||
j.at("LutPath").get_to(param.LutPath);
|
||||
j.at("TextLutPath").get_to(param.TextLutPath);
|
||||
j.at("FlatBlackPath").get_to(param.Flat_BwPath);
|
||||
j.at("FlatWhitePath").get_to(param.Flat_WhitePath);
|
||||
}
|
||||
|
||||
void CorrectParam::SaveCorrectParam(FPGAConfigParam_8478 &parms)
|
||||
{
|
||||
std::lock_guard<std::mutex> lc(m_lock);
|
||||
auto filejson = GetCorrectParams_8478();
|
||||
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_R, parms.GainB_R, sizeof(parms.GainB_R));
|
||||
memcpy(filejson[i].GainF_R, parms.GainF_R, sizeof(parms.GainF_R));
|
||||
memcpy(filejson[i].OffsetB_R, parms.OffsetB_R, sizeof(parms.OffsetB_R));
|
||||
memcpy(filejson[i].OffsetF_R, parms.OffsetF_R, sizeof(parms.OffsetF_R));
|
||||
|
||||
memcpy(filejson[i].GainB_G, parms.GainB_G, sizeof(parms.GainB_G));
|
||||
memcpy(filejson[i].GainF_G, parms.GainF_G, sizeof(parms.GainF_G));
|
||||
memcpy(filejson[i].OffsetB_G, parms.OffsetB_G, sizeof(parms.OffsetB_G));
|
||||
memcpy(filejson[i].OffsetF_G, parms.OffsetF_G, sizeof(parms.OffsetF_G));
|
||||
|
||||
memcpy(filejson[i].GainB_B, parms.GainB_B, sizeof(parms.GainB_B));
|
||||
memcpy(filejson[i].GainF_B, parms.GainF_B, sizeof(parms.GainF_B));
|
||||
memcpy(filejson[i].OffsetB_B, parms.OffsetB_B, sizeof(parms.OffsetB_B));
|
||||
memcpy(filejson[i].OffsetF_B, parms.OffsetF_B, sizeof(parms.OffsetF_B));
|
||||
filejson[i].LutPath = parms.LutPath;
|
||||
filejson[i].TextLutPath = parms.TextLutPath;
|
||||
filejson[i].Flat_BwPath = parms.Flat_BwPath;
|
||||
filejson[i].Flat_WhitePath = parms.Flat_WhitePath;
|
||||
filejson[i].Sp = parms.Sp;
|
||||
filejson[i].HRatio = parms.HRatio;
|
||||
filejson[i].VRatio = parms.VRatio;
|
||||
break;
|
||||
}
|
||||
}
|
||||
json j = json::array();
|
||||
for (size_t i = 0; i < filejson.size(); i++)
|
||||
{
|
||||
json t_j;
|
||||
to_json(t_j, filejson[i]);
|
||||
j.push_back(t_j);
|
||||
}
|
||||
ofstream ofs(JSONPATH_8478);
|
||||
ofs << std::setw(4) << j << std::endl;
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
FPGAConfigParam_8478 CorrectParam::GetFpgaparam_8478(int dpi, int mode)
|
||||
{
|
||||
std::lock_guard<std::mutex> lc(m_lock);
|
||||
FPGAConfigParam_8478 param;
|
||||
auto filejson = GetCorrectParams_8478();
|
||||
for (size_t i = 0; i < filejson.size(); i++)
|
||||
{
|
||||
if ((filejson[i].ColorMode == mode) &&
|
||||
(filejson[i].DpiMode == dpi))
|
||||
{
|
||||
param = filejson[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
FPGAConfigParam_8478 CorrectParam::GetFpgaparam_8478_HL_Lvds(int dpi, int mode)
|
||||
{
|
||||
std::lock_guard<std::mutex> lc(m_lock);
|
||||
FPGAConfigParam_8478 param;
|
||||
auto filejson = GetCorrectParams_8478_HL_Lvds();
|
||||
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::set_sp(int dpi, int mode,uint32_t sp)
|
||||
{
|
||||
auto param = GetFpgaparam(dpi,mode);
|
||||
param.Sp = sp;
|
||||
SaveCorrectParam(param);
|
||||
}
|
||||
void CorrectParam::set_sp_8478(int dpi, int mode,uint32_t sp)
|
||||
{
|
||||
auto param = GetFpgaparam_8478(dpi,mode);
|
||||
param.Sp = sp;
|
||||
SaveCorrectParam(param);
|
||||
}
|
||||
|
||||
void CorrectParam::set_sp_8458_color_lvds(int dpi,int mode,uint32_t sp)
|
||||
{
|
||||
auto param = GetFpgaparam_8458_color_Lvds(dpi,mode);
|
||||
param.Sp = sp;
|
||||
SaveCorrectParam(param);
|
||||
}
|
||||
|
||||
void CorrectParam::set_sp_8748_HL_lvds(int dpi,int mode,uint32_t sp)
|
||||
{
|
||||
auto param = GetFpgaparam_8478_HL_Lvds(dpi,mode);
|
||||
param.Sp = sp;
|
||||
SaveCorrectParam(param);
|
||||
}
|
||||
|
||||
|
||||
CorrectParam m_static_correctparam;
|
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
#include "json.hpp"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "CameraParam.h"
|
||||
#include <mutex>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
class CorrectParam
|
||||
{
|
||||
public:
|
||||
CorrectParam(/* args */);
|
||||
~CorrectParam();
|
||||
|
||||
|
||||
FPGAConfigParam GetFpgaparam(int dpi, int mode);
|
||||
FPGAConfigParam GetFpgaparam_8458_color_Lvds(int dpi, int mode);
|
||||
void SaveCorrectParam(FPGAConfigParam &parms);
|
||||
|
||||
FPGAConfigParam_8478 GetFpgaparam_8478(int dpi, int mode);
|
||||
FPGAConfigParam_8478 GetFpgaparam_8478_HL_Lvds(int dpi, int mode);
|
||||
void SaveCorrectParam(FPGAConfigParam_8478 &parms);
|
||||
|
||||
void set_sp(int dpi, int mode,uint32_t sp);
|
||||
void set_sp_8478(int dpi, int mode,uint32_t sp);
|
||||
void set_sp_8458_color_lvds(int dpi,int mode,uint32_t sp);
|
||||
void set_sp_8748_HL_lvds(int dpi,int mode,uint32_t sp);
|
||||
|
||||
private:
|
||||
void initdefaultpapram();
|
||||
std::vector<FPGAConfigParam> GetCorrectParams();
|
||||
std::vector<FPGAConfigParam> GetCorrectParams_8458_Color_Lvds();
|
||||
void to_json(json &j, FPGAConfigParam ¶m);
|
||||
void from_json(json &j, FPGAConfigParam ¶m);
|
||||
|
||||
|
||||
std::vector<FPGAConfigParam_8478> GetCorrectParams_8478();
|
||||
std::vector<FPGAConfigParam_8478> GetCorrectParams_8478_HL_Lvds();
|
||||
void to_json(json &j, FPGAConfigParam_8478 ¶m);
|
||||
void from_json(json &j, FPGAConfigParam_8478 ¶m);
|
||||
|
||||
std::mutex m_lock;
|
||||
};
|
||||
|
||||
|
||||
extern CorrectParam m_static_correctparam;
|
||||
static CorrectParam& Get_Static_CorrectParam()
|
||||
{
|
||||
return m_static_correctparam;
|
||||
}
|
|
@ -0,0 +1,495 @@
|
|||
//
|
||||
// Created by Nick on 2019/4/7.
|
||||
//
|
||||
#include "FpgaComm.h"
|
||||
#include <thread>
|
||||
#include "uartregsaccess.h"
|
||||
#include "config.h"
|
||||
#include <iostream>
|
||||
|
||||
#define Reg(x) (fpgaParams.x)
|
||||
#define RegIndex(x) (std::distance((unsigned int *)&fpgaParams, (unsigned int *)&fpgaParams.x))
|
||||
#define ReadReg(x) read(RegIndex(x), *((unsigned int *)&fpgaParams.x))
|
||||
#define WriteReg(x) write(RegIndex(x), *((unsigned int *)&fpgaParams.x))
|
||||
#define WR_Reg(x) (WriteReg(x), ReadReg(x))
|
||||
|
||||
#define CO(x) std::cout << #x << " : " << RegIndex(x) << std::endl
|
||||
|
||||
FpgaComm::FpgaComm()
|
||||
{
|
||||
m_regsAccess.reset(new UartRegsAccess(FPGA_UART, 921600, 0x03, 0x83));
|
||||
// update(0);
|
||||
|
||||
// Reg(AledR).sample = 256;
|
||||
// WR_Reg(AledR);
|
||||
}
|
||||
|
||||
void FpgaComm::regsAccess_reset(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
if (!m_regsAccess.get())
|
||||
m_regsAccess.reset(new UartRegsAccess(FPGA_UART, 921600, 0x03, 0x83));
|
||||
return;
|
||||
}
|
||||
if (m_regsAccess.get())
|
||||
m_regsAccess.reset();
|
||||
}
|
||||
|
||||
bool FpgaComm::read(unsigned int addr, unsigned int &val)
|
||||
{
|
||||
if (m_regsAccess.get())
|
||||
return m_regsAccess->read(addr, val);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FpgaComm::write(unsigned int addr, unsigned int val)
|
||||
{
|
||||
if (m_regsAccess.get())
|
||||
return m_regsAccess->write(addr, val);
|
||||
return false;
|
||||
}
|
||||
|
||||
void FpgaComm::setFrameHeight(int height)
|
||||
{
|
||||
Reg(frame).height = height;
|
||||
WR_Reg(frame);
|
||||
}
|
||||
|
||||
int FpgaComm::getFrameHeight()
|
||||
{
|
||||
return Reg(frame).height;
|
||||
}
|
||||
|
||||
void FpgaComm::setFrameNum(int num)
|
||||
{
|
||||
Reg(frame).num = num;
|
||||
WR_Reg(frame);
|
||||
}
|
||||
|
||||
void FpgaComm::enableLed(bool bEnable)
|
||||
{
|
||||
Reg(AledR).ledEnable = bEnable;
|
||||
WR_Reg(AledR);
|
||||
#ifdef HAS_UV
|
||||
Reg(BledR).ledEnable = bEnable;
|
||||
WR_Reg(BledR);
|
||||
#else
|
||||
Reg(BledR).ledEnable = !bEnable;
|
||||
WR_Reg(BledR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FpgaComm::enableUV(bool enable)
|
||||
{
|
||||
#ifdef HAS_UV
|
||||
isUVEnable = enable;
|
||||
Reg(BledR).ledEnable = isUVEnable;
|
||||
WR_Reg(BledR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FpgaComm::capture()
|
||||
{
|
||||
ReadReg(cmd);
|
||||
Reg(cmd).cmd = 0;
|
||||
WriteReg(cmd);
|
||||
Reg(cmd).cmd = 1;
|
||||
WriteReg(cmd);
|
||||
}
|
||||
|
||||
int FpgaComm::getRegs(int addr)
|
||||
{
|
||||
return fpgaParams.regs[addr];
|
||||
}
|
||||
|
||||
void FpgaComm::setRegs(int addr, int value)
|
||||
{
|
||||
fpgaParams.regs[addr] = value;
|
||||
write(addr, value);
|
||||
read(addr, fpgaParams.regs[addr]);
|
||||
}
|
||||
|
||||
void FpgaComm::setAGain(int indexGain, int value)
|
||||
{
|
||||
int index = indexGain;
|
||||
int val; // = value
|
||||
value >= 511 ? val = 511 : val = value;
|
||||
index++;
|
||||
fpgaParams.Aad.ad0_addr = index * 2;
|
||||
fpgaParams.Aad.ad1_addr = fpgaParams.Aad.ad0_addr + 1;
|
||||
fpgaParams.Aad.ad0_value = val;
|
||||
fpgaParams.Aad.ad1_value = val > 255 ? 1 : 0;
|
||||
fpgaParams.Aad.ad0_rw = 0;
|
||||
fpgaParams.Aad.ad1_rw = 0;
|
||||
write(0x04, *(int *)&fpgaParams.Aad);
|
||||
Reg(mode).adcA = 1;
|
||||
WriteReg(mode);
|
||||
Reg(mode).adcA = 0;
|
||||
WriteReg(mode);
|
||||
}
|
||||
|
||||
void FpgaComm::setBGain(int indexGain, int value)
|
||||
{
|
||||
int index = indexGain;
|
||||
int val; // = value
|
||||
value >= 511 ? val = 511 : val = value;
|
||||
index++;
|
||||
fpgaParams.Bad.ad0_addr = index * 2;
|
||||
fpgaParams.Bad.ad1_addr = index * 2 + 1;
|
||||
fpgaParams.Bad.ad0_value = val;
|
||||
fpgaParams.Bad.ad1_value = val > 255 ? 1 : 0;
|
||||
fpgaParams.Bad.ad0_rw = 0;
|
||||
fpgaParams.Bad.ad1_rw = 0;
|
||||
write(0x07, *(int *)&fpgaParams.Bad);
|
||||
Reg(mode).adcB = 1;
|
||||
WriteReg(mode);
|
||||
Reg(mode).adcB = 0;
|
||||
WriteReg(mode);
|
||||
}
|
||||
|
||||
void FpgaComm::setAOffset(int indexOffset, int value)
|
||||
{
|
||||
Reg(Aad).ad0_rw = 0;
|
||||
Reg(Aad).ad1_rw = 0;
|
||||
Reg(Aad).ad0_addr = indexOffset + 0x0e;
|
||||
Reg(Aad).ad1_addr = 0x14;
|
||||
Reg(Aad).ad0_value = value;
|
||||
WriteReg(Aad);
|
||||
Reg(mode).adcA = 1;
|
||||
WriteReg(mode);
|
||||
Reg(mode).adcA = 0;
|
||||
WriteReg(mode);
|
||||
}
|
||||
|
||||
void FpgaComm::setBOffset(int indexOffset, int value)
|
||||
{
|
||||
Reg(Bad).ad0_rw = 0;
|
||||
Reg(Bad).ad1_rw = 0;
|
||||
Reg(Bad).ad0_addr = indexOffset + 0x0e;
|
||||
Reg(Bad).ad1_addr = 0x14;
|
||||
Reg(Bad).ad0_value = value;
|
||||
WriteReg(Bad);
|
||||
Reg(mode).adcB = 1;
|
||||
WriteReg(mode);
|
||||
Reg(mode).adcB = 0;
|
||||
WriteReg(mode);
|
||||
}
|
||||
|
||||
void FpgaComm::setAExposureR(int value)
|
||||
{
|
||||
Reg(AledR).ledR = value;
|
||||
WR_Reg(AledR);
|
||||
}
|
||||
|
||||
void FpgaComm::setAExposureG(int value)
|
||||
{
|
||||
Reg(AledGB).ledG = value;
|
||||
WR_Reg(AledGB);
|
||||
}
|
||||
|
||||
void FpgaComm::setAExposureB(int value)
|
||||
{
|
||||
Reg(AledGB).ledB = value;
|
||||
WR_Reg(AledGB);
|
||||
}
|
||||
|
||||
void FpgaComm::setAExposureUV(int value)
|
||||
{
|
||||
#ifdef HAS_UV
|
||||
Reg(UVLed).ledASide = value;
|
||||
WR_Reg(UVLed);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FpgaComm::setBExposureR(int value)
|
||||
{
|
||||
Reg(BledR).ledR = value;
|
||||
WR_Reg(BledR);
|
||||
}
|
||||
|
||||
void FpgaComm::setBExposureG(int value)
|
||||
{
|
||||
Reg(BledGB).ledG = value;
|
||||
WR_Reg(BledGB);
|
||||
}
|
||||
|
||||
void FpgaComm::setBExposureB(int value)
|
||||
{
|
||||
Reg(BledGB).ledB = value;
|
||||
WR_Reg(BledGB);
|
||||
}
|
||||
|
||||
void FpgaComm::setBExpousreUV(int value)
|
||||
{
|
||||
#ifdef HAS_UV
|
||||
Reg(UVLed).ledBSide = value;
|
||||
WR_Reg(UVLed);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FpgaComm::setSp(int value)
|
||||
{
|
||||
Reg(mode).sp = value;
|
||||
WR_Reg(mode);
|
||||
}
|
||||
|
||||
int FpgaComm::getSp()
|
||||
{
|
||||
return Reg(mode).sp;
|
||||
}
|
||||
|
||||
void FpgaComm::setColorMode(int mode)
|
||||
{
|
||||
Reg(mode).colorMode = mode;
|
||||
WR_Reg(mode);
|
||||
}
|
||||
|
||||
int FpgaComm::getColorMode()
|
||||
{
|
||||
return Reg(mode).colorMode;
|
||||
}
|
||||
|
||||
void FpgaComm::setSample(int sample)
|
||||
{
|
||||
Reg(mode).sample = sample;
|
||||
WR_Reg(mode);
|
||||
Reg(AledR).sample = sample;
|
||||
WR_Reg(AledR);
|
||||
}
|
||||
|
||||
void FpgaComm::EnableTest(bool bTest)
|
||||
{
|
||||
Reg(mode).selftest = bTest;
|
||||
WR_Reg(mode);
|
||||
}
|
||||
|
||||
int FpgaComm::IsTest()
|
||||
{
|
||||
return Reg(mode).selftest;
|
||||
}
|
||||
|
||||
int FpgaComm::getSample()
|
||||
{
|
||||
return Reg(mode).sample;
|
||||
}
|
||||
|
||||
void FpgaComm::setDpi(int dpi)
|
||||
{
|
||||
Reg(mode).dpi = dpi;
|
||||
WR_Reg(mode);
|
||||
}
|
||||
|
||||
int FpgaComm::getDpi()
|
||||
{
|
||||
return Reg(mode).dpi;
|
||||
}
|
||||
|
||||
// 20190626 YHP autoTrig function
|
||||
void FpgaComm::setTrigMode(bool isArmMode)
|
||||
{
|
||||
unsigned int tmp;
|
||||
read(0x0b, tmp);
|
||||
if (!isArmMode)
|
||||
{ // default value+ ARM MODE,bit27 =0;
|
||||
fpgaParams.TrigMode = tmp & 0XFBFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
fpgaParams.TrigMode = tmp | (1 << 26);
|
||||
}
|
||||
WR_Reg(TrigMode);
|
||||
}
|
||||
void FpgaComm::setDelayTime(int value)
|
||||
{
|
||||
// Reg(DelayTime) = value;
|
||||
// WR_Reg(DelayTime);
|
||||
}
|
||||
|
||||
void FpgaComm::update(int times)
|
||||
{
|
||||
std::uint32_t tmp_reg = 0;
|
||||
for (int i = 0; i < 22; i++)
|
||||
{
|
||||
read(i, tmp_reg);
|
||||
printf("times[%d] reg[%d] = 0x%08x \n", times, i, tmp_reg);
|
||||
}
|
||||
}
|
||||
|
||||
void FpgaComm::enableJamCheck(bool b)
|
||||
{
|
||||
// Reg(BledR).user_define.led_sample.jamEnable = b;
|
||||
// WR_Regs(0x08);
|
||||
}
|
||||
|
||||
void FpgaComm::resetADC()
|
||||
{
|
||||
|
||||
fpgaParams.Aad.ad0_rw = 0;
|
||||
fpgaParams.Aad.ad0_addr = 0;
|
||||
fpgaParams.Aad.ad0_value = 0;
|
||||
fpgaParams.Aad.ad1_rw = 0;
|
||||
fpgaParams.Aad.ad1_addr = 0;
|
||||
fpgaParams.Aad.ad1_value = 0;
|
||||
WR_Reg(Aad);
|
||||
fpgaParams.mode.adcA = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcA = 0;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.Bad.ad0_rw = 0;
|
||||
fpgaParams.Bad.ad0_addr = 0;
|
||||
fpgaParams.Bad.ad0_value = 0;
|
||||
fpgaParams.Bad.ad1_rw = 0;
|
||||
fpgaParams.Bad.ad1_addr = 0;
|
||||
fpgaParams.Bad.ad1_value = 0;
|
||||
WR_Reg(Bad);
|
||||
fpgaParams.mode.adcB = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcB = 0;
|
||||
WR_Reg(mode);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
fpgaParams.Aad.ad0_rw = 0;
|
||||
fpgaParams.Aad.ad0_addr = 0;
|
||||
fpgaParams.Aad.ad0_value = 7;
|
||||
fpgaParams.Aad.ad1_rw = 0;
|
||||
fpgaParams.Aad.ad1_addr = 0;
|
||||
fpgaParams.Aad.ad1_value = 7;
|
||||
WR_Reg(Aad);
|
||||
fpgaParams.mode.adcA = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcA = 0;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.Bad.ad0_rw = 0;
|
||||
fpgaParams.Bad.ad0_addr = 0;
|
||||
fpgaParams.Bad.ad0_value = 7;
|
||||
fpgaParams.Bad.ad1_rw = 0;
|
||||
fpgaParams.Bad.ad1_addr = 0;
|
||||
fpgaParams.Bad.ad1_value = 7;
|
||||
WR_Reg(Bad);
|
||||
fpgaParams.mode.adcB = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcB = 0;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.Aad.ad0_rw = 0;
|
||||
fpgaParams.Aad.ad0_addr = 1;
|
||||
fpgaParams.Aad.ad0_value = 0x50;
|
||||
fpgaParams.Aad.ad1_rw = 0;
|
||||
fpgaParams.Aad.ad1_addr = 1;
|
||||
fpgaParams.Aad.ad1_value = 0x50;
|
||||
WR_Reg(Aad);
|
||||
fpgaParams.mode.adcA = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcA = 0;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.Bad.ad0_rw = 0;
|
||||
fpgaParams.Bad.ad0_addr = 1;
|
||||
fpgaParams.Bad.ad0_value = 0x50;
|
||||
fpgaParams.Bad.ad1_rw = 0;
|
||||
fpgaParams.Bad.ad1_addr = 1;
|
||||
fpgaParams.Bad.ad1_value = 0x50;
|
||||
WR_Reg(Bad);
|
||||
fpgaParams.mode.adcB = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcB = 0;
|
||||
WR_Reg(mode);
|
||||
}
|
||||
|
||||
void FpgaComm::setEnTestCol(bool en)
|
||||
{
|
||||
Reg(AledR).en_test_color = en ? 1 : 0;
|
||||
WR_Reg(AledR);
|
||||
}
|
||||
|
||||
void FpgaComm::setEnTestBit(bool en)
|
||||
{
|
||||
Reg(AledR).en_test = en ? 1 : 0;
|
||||
WR_Reg(AledR);
|
||||
}
|
||||
|
||||
void FpgaComm::setVsp(unsigned int Aside, unsigned int BSide)
|
||||
{
|
||||
CISVSP vsp;
|
||||
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);
|
||||
m_regsAccess->write(13, vsp.value);
|
||||
}
|
||||
|
||||
void FpgaComm::setFrame_interval_min(int min)
|
||||
{
|
||||
fpgaParams.FrameInterval.Frame_Interval_min = min;
|
||||
fpgaParams.FrameInterval.reversed = 0;
|
||||
WR_Reg(FrameInterval);
|
||||
}
|
||||
|
||||
int FpgaComm::getFrame_interval_min()
|
||||
{
|
||||
uint32_t value = 0;
|
||||
fpgaParams.FrameInterval.reversed = 0;
|
||||
read(0x0c, value);
|
||||
fpgaParams.FrameInterval = *(CisFrameInterval *)&value;
|
||||
return fpgaParams.FrameInterval.Frame_Interval_min;
|
||||
}
|
||||
|
||||
void FpgaComm::setFrame_interval_max(int max)
|
||||
{
|
||||
fpgaParams.FrameInterval.Frame_Interval_max = max;
|
||||
fpgaParams.FrameInterval.reversed = 0;
|
||||
WR_Reg(FrameInterval);
|
||||
}
|
||||
|
||||
int FpgaComm::getFrame_interval_max()
|
||||
{
|
||||
uint32_t value = 0;
|
||||
fpgaParams.FrameInterval.reversed = 0;
|
||||
read(0x0c, value);
|
||||
fpgaParams.FrameInterval = *(CisFrameInterval *)&value;
|
||||
return fpgaParams.FrameInterval.Frame_Interval_max;
|
||||
}
|
||||
|
||||
unsigned int FpgaComm::getFrame_counter_val()
|
||||
{
|
||||
uint32_t crt_frame_count = 0;
|
||||
uint32_t reg8 = 0;
|
||||
|
||||
read(8, reg8);
|
||||
// write(8,reg8 & 0x8);
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||
write(8, reg8 & 0xfffffff7); // off stop snap
|
||||
read(8, reg8);
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||
read(0x10, crt_frame_count);
|
||||
|
||||
if (crt_frame_count & 0xffff <= 0)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
read(0x10, crt_frame_count);
|
||||
printf("try %d times read frame count,frame_count = %d \n", i, crt_frame_count);
|
||||
if (crt_frame_count & 0xffff > 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 & 0xffff;
|
||||
}
|
||||
|
||||
int FpgaComm::getFrameNum()
|
||||
{
|
||||
return fpgaParams.frame.num;
|
||||
}
|
||||
|
||||
void FpgaComm::set_cis_type(bool isA3_CIS)
|
||||
{
|
||||
fpgaParams.AledR.cis_type = isA3_CIS ? 1 : 0;
|
||||
}
|
||||
|
||||
void FpgaComm::set_8478_type(bool is_HL)
|
||||
{
|
||||
ReadReg(cmd);
|
||||
Reg(cmd).cis_HL = is_HL;
|
||||
WriteReg(cmd);
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "regsaccess.h"
|
||||
|
||||
#ifdef HAS_UV
|
||||
#define MAX_REGS 0x0e
|
||||
#else
|
||||
#define MAX_REGS 0x0e
|
||||
#endif
|
||||
|
||||
typedef struct Frame_FPGA
|
||||
{
|
||||
unsigned short int height;
|
||||
unsigned short 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 adc_confif_hz : 4;
|
||||
unsigned int cis_HL : 1; //true 华菱 8478 lvds
|
||||
unsigned int reserved : 26;
|
||||
} CmdFpga;
|
||||
|
||||
typedef struct STATUS_FPGA
|
||||
{
|
||||
unsigned int status : 1; // start : 1 , stop : 0
|
||||
unsigned int reserved : 31;
|
||||
} StatusFpga;
|
||||
|
||||
typedef struct Ad_Gain
|
||||
{
|
||||
unsigned short int gain_low8 : 8;
|
||||
unsigned short int gain_hight : 1;
|
||||
unsigned int reserved : 23;
|
||||
} AdGain;
|
||||
|
||||
typedef struct CIS_AD_Gain
|
||||
{
|
||||
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:写;
|
||||
} CisAdGain;
|
||||
|
||||
typedef struct CIS_LED_RF
|
||||
{
|
||||
unsigned short int ledEnable : 1;
|
||||
unsigned short int fanMode : 2;
|
||||
unsigned short int jamEnable : 1;
|
||||
unsigned short int sample : 9;
|
||||
unsigned short int reserved : 3;
|
||||
unsigned short int ledR;
|
||||
} CisLedRF;
|
||||
|
||||
typedef struct CIS_LED_R
|
||||
{
|
||||
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;
|
||||
unsigned short int reserved : 3;
|
||||
unsigned short int ledR;
|
||||
} CisLedR;
|
||||
|
||||
typedef struct CIS_LED_GB
|
||||
{
|
||||
unsigned short int ledG;
|
||||
unsigned short int ledB;
|
||||
} CisLedGB;
|
||||
|
||||
typedef struct CIS_LED_UV
|
||||
{
|
||||
unsigned short int ledASide;
|
||||
unsigned short int ledBSide;
|
||||
} CisLedUv;
|
||||
|
||||
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;
|
||||
unsigned int reversed; // 0x0e
|
||||
unsigned int fpgaversion; // 0x0f
|
||||
// unsigned int ConFrameCount;//多帧计数
|
||||
};
|
||||
unsigned int regs[16];
|
||||
} FpgaParams;
|
||||
|
||||
typedef union CIS_VSP
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int ASide_VSP : 9;
|
||||
unsigned int BSide_VSP : 9;
|
||||
unsigned int reserved : 14;
|
||||
} bits;
|
||||
int value;
|
||||
} CISVSP;
|
||||
|
||||
class FpgaComm : public IRegsAccess
|
||||
{
|
||||
public:
|
||||
FpgaComm();
|
||||
virtual ~FpgaComm() {}
|
||||
|
||||
void reset();
|
||||
void regsAccess_reset(bool enable);
|
||||
void setRegs(int addr, int value);
|
||||
int getRegs(int addr);
|
||||
void setFrameHeight(int height);
|
||||
int getFrameHeight();
|
||||
void setFrameNum(int num);
|
||||
void enableLed(bool bEnable);
|
||||
void enableUV(bool enable);
|
||||
void capture();
|
||||
void setAGain(int indexGain, int value);
|
||||
void setBGain(int indexGain, int value);
|
||||
void setAOffset(int indexOffset, int value);
|
||||
void setBOffset(int indexOffset, int value);
|
||||
|
||||
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 setSp(int value);
|
||||
int getSp();
|
||||
|
||||
void EnableTest(bool bTest);
|
||||
int IsTest();
|
||||
|
||||
void setColorMode(int mode);
|
||||
int getColorMode();
|
||||
|
||||
void setDpi(int dpi);
|
||||
int getDpi();
|
||||
|
||||
void setSample(int sample);
|
||||
int getSample();
|
||||
|
||||
// 20190626 YHP autoTrig function
|
||||
void setDelayTime(int value);
|
||||
void setTrigMode(bool isArmMode);
|
||||
|
||||
void update(int times);
|
||||
void enableJamCheck(bool b);
|
||||
void resetADC();
|
||||
void setVsp(unsigned int Aside, unsigned int BSide);
|
||||
|
||||
void setFrame_interval_min(int min);
|
||||
int getFrame_interval_min();
|
||||
void setFrame_interval_max(int max);
|
||||
int getFrame_interval_max();
|
||||
unsigned int getFrame_counter_val();
|
||||
int getFrameNum();
|
||||
void set_cis_type(bool isA3_CIS);
|
||||
void set_8478_type(bool is_HL);
|
||||
|
||||
virtual bool write(unsigned int addr, unsigned int val);
|
||||
virtual bool read(unsigned int addr, unsigned int &val);
|
||||
|
||||
private:
|
||||
FpgaParams fpgaParams;
|
||||
std::shared_ptr<IRegsAccess> m_regsAccess;
|
||||
};
|
|
@ -0,0 +1,109 @@
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
std::vector<double> caculate_abcd(std::vector<std::pair<double, double>> point)
|
||||
{
|
||||
int MaxElement = point.size() - 1;
|
||||
// 计算常数f
|
||||
double f = point[0].second;
|
||||
// 求解
|
||||
int n, m;
|
||||
|
||||
std::vector<std::vector<double>> a;
|
||||
|
||||
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] = pow(point[i + 1].first, MaxElement - j);
|
||||
a[i][MaxElement] = point[i + 1].second - f;
|
||||
}
|
||||
|
||||
int i, j;
|
||||
n = MaxElement;
|
||||
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
double max = 0;
|
||||
double imax = 0;
|
||||
for (i = j; i < n; i++)
|
||||
{
|
||||
if (imax < fabs(a[i][j]))
|
||||
{
|
||||
imax = fabs(a[i][j]);
|
||||
max = a[i][j]; // 得到各行中所在列最大元素
|
||||
m = i;
|
||||
}
|
||||
}
|
||||
if (fabs(a[j][j]) != max)
|
||||
{
|
||||
double b = 0;
|
||||
for (int k = j; k < n + 1; k++)
|
||||
{
|
||||
b = a[j][k];
|
||||
a[j][k] = a[m][k];
|
||||
a[m][k] = b;
|
||||
}
|
||||
}
|
||||
|
||||
for (int r = j; r < n + 1; r++)
|
||||
{
|
||||
a[j][r] = a[j][r] / max; // 让该行的所在列除以所在列的第一个元素,目的是让首元素为1
|
||||
}
|
||||
|
||||
for (i = j + 1; i < n; i++)
|
||||
{
|
||||
double c = a[i][j];
|
||||
if (c == 0.0)
|
||||
continue;
|
||||
for (int s = j; s < n + 1; s++)
|
||||
{
|
||||
a[i][s] = a[i][s] - a[j][s] * c; // 前后行数相减,使下一行或者上一行的首元素为0
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = n - 2; i >= 0; i--)
|
||||
{
|
||||
for (j = i + 1; j < n; j++)
|
||||
{
|
||||
a[i][n] = a[i][n] - a[j][n] * a[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<double> result;
|
||||
for (int k = 0; k < n; k++)
|
||||
result.push_back(a[k][n]);
|
||||
result.push_back(f);
|
||||
return result;
|
||||
}
|
||||
|
||||
double caculate_value(const std::vector<double> &abcd, double x)
|
||||
{
|
||||
return abcd[0] * x * x * x + abcd[1] * x * x + abcd[2] * x + abcd[3];
|
||||
}
|
||||
|
||||
void brightness(cv::Mat &lut, int alpha = 170)
|
||||
{
|
||||
std::vector<std::pair<double, double>> pos;
|
||||
pos.push_back(std::pair<double, double>(0, 0));
|
||||
pos.push_back(std::pair<double, double>(64, 64));
|
||||
pos.push_back(std::pair<double, double>(alpha, 255));
|
||||
pos.push_back(std::pair<double, double>(255, 255));
|
||||
std::vector<double> abcd = caculate_abcd(pos);
|
||||
|
||||
uchar table[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
table[i] = static_cast<uchar>(caculate_value(abcd, i));
|
||||
|
||||
uchar *ptr = lut.data;
|
||||
for (int i = 0, length = lut.total() * lut.channels(); i < length; i++)
|
||||
ptr[i] = table[ptr[i]];
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include "regsaccess.h"
|
||||
#include "commondef.h"
|
||||
#include "CorrectParam.h"
|
||||
#include "opencv2\opencv.hpp"
|
||||
|
||||
class ICapturer
|
||||
{
|
||||
public:
|
||||
virtual ~ICapturer() {}
|
||||
virtual void Fpga_regsAccess_reset(bool enable) = 0;
|
||||
virtual void open() = 0;
|
||||
virtual void open(HGScanConfig config, FPGAConfigParam fpgaparam) = 0;
|
||||
virtual void open(HGScanConfig config, FPGAConfigParam_8478 fpgaparam){};
|
||||
virtual void snap(frame_data_info info) {}
|
||||
virtual cv::Size frame_data_size() { return {0, 0}; }
|
||||
virtual void close() = 0;
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual bool is_runing() = 0;
|
||||
virtual void snap() = 0;
|
||||
virtual void stopsnap() = 0;
|
||||
virtual int getautosizeheight() = 0;
|
||||
virtual void set_size(int width, int height) = 0;
|
||||
virtual void *readFrame(int timeout) = 0;
|
||||
|
||||
virtual void set_gain(int ix, int val) = 0;
|
||||
virtual void set_offset(int ix, int val) = 0;
|
||||
virtual void set_expo(int ix, int val) = 0;
|
||||
virtual uint32_t multi_frame_counts() { return 0; }
|
||||
virtual uint32_t multi_curr_snap_index() { return 0; }
|
||||
|
||||
virtual std::shared_ptr<IRegsAccess> regs() = 0;
|
||||
virtual void reset() = 0;
|
||||
virtual int width() = 0;
|
||||
virtual int height() = 0;
|
||||
virtual int color() = 0;
|
||||
virtual void init_autocorrect(int colormode = 0) = 0;
|
||||
virtual void setcapturecall(std::function<void(int, std::string)> callback) = 0;
|
||||
virtual frame_data_info ReadMultiFrame(int state) { return {0}; }
|
||||
virtual void single_correct(std::uint32_t mode) = 0;
|
||||
virtual void set_fpga_vsp(int a, int b) {}
|
||||
virtual cv::Mat read_one_frame() { return cv::Mat(); }
|
||||
void set_gscancap(GScanCap cap){ m_gscancap = cap;}
|
||||
|
||||
protected:
|
||||
GScanCap m_gscancap;
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,74 @@
|
|||
#pragma once
|
||||
#include "ICapturer.h"
|
||||
|
||||
class FpgaComm;
|
||||
class gVideo;
|
||||
class Gpio;
|
||||
|
||||
class MonoCapturer : public ICapturer
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
MonoCapturer(/* args */);
|
||||
virtual ~MonoCapturer();
|
||||
virtual void open();
|
||||
virtual void open(HGScanConfig config, FPGAConfigParam fpgaparam);
|
||||
virtual void close();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool is_runing();
|
||||
virtual void snap();
|
||||
virtual void stopsnap();
|
||||
virtual int getautosizeheight();
|
||||
virtual void set_size(int width, int height);
|
||||
virtual void set_sp(int sp);
|
||||
|
||||
virtual void *readFrame(int timeout);
|
||||
|
||||
virtual void set_gain(int ix, int val);
|
||||
virtual void set_offset(int ix, int val);
|
||||
virtual void set_expo(int ix, int val);
|
||||
|
||||
virtual std::shared_ptr<IRegsAccess> regs();
|
||||
virtual void reset();
|
||||
virtual int width();
|
||||
virtual int height();
|
||||
virtual int color();
|
||||
virtual void init_autocorrect(int colormode);
|
||||
virtual void setcapturecall(std::function<void(int, std::string)> callback)
|
||||
{
|
||||
m_captureCallback = callback;
|
||||
};
|
||||
virtual void Fpga_regsAccess_reset(bool enable);
|
||||
virtual void single_correct(std::uint32_t mode) override;
|
||||
virtual void set_fpga_vsp(int a, int b);
|
||||
|
||||
private:
|
||||
void configFPGAParam(int mode, int dpi);
|
||||
void openDevice(int dpi, int mode);
|
||||
void creatcorrectconfig(int dpi, int mode);
|
||||
bool saveLutImg(int dpi, int mode, bool black);
|
||||
void correctcolor(int correctmode);
|
||||
void fpga_reset();
|
||||
void fpga_reload();
|
||||
void init_lutdate();
|
||||
|
||||
private:
|
||||
std::function<void(int, std::string)> m_captureCallback;
|
||||
std::shared_ptr<gVideo> video;
|
||||
std::shared_ptr<Gpio> vdd_cis_3voff_pin;
|
||||
std::shared_ptr<Gpio> vdd_vis_5ven_pin;
|
||||
std::shared_ptr<Gpio> reset_pin;
|
||||
std::shared_ptr<Gpio> image_in_transfer_pin;
|
||||
std::shared_ptr<Gpio> initDone_pin;
|
||||
std::shared_ptr<Gpio> fpgaLoad;
|
||||
std::shared_ptr<FpgaComm> fpgaComm;
|
||||
std::shared_ptr<Gpio> fpga_conf_initn;
|
||||
std::shared_ptr<Gpio> fpga_conf_done;
|
||||
bool bcorrecting;
|
||||
std::thread m_correctthread;
|
||||
unsigned int m_fpgaversion;
|
||||
HGScanConfig m_config;
|
||||
FPGAConfigParam m_fpgaparam;
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,171 @@
|
|||
#pragma once
|
||||
#include "ICapturer.h"
|
||||
#include "ThreadPool.h"
|
||||
class FpgaComm;
|
||||
class gVideo;
|
||||
class Gpio;
|
||||
|
||||
class MultiFrameCapture : public ICapturer
|
||||
{
|
||||
public:
|
||||
MultiFrameCapture();
|
||||
virtual ~MultiFrameCapture();
|
||||
virtual void open();
|
||||
virtual void open(HGScanConfig config, FPGAConfigParam fpgaparam){};
|
||||
virtual void open(HGScanConfig config, FPGAConfigParam_8478 fpgaparam);
|
||||
virtual void close();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool is_runing();
|
||||
virtual void snap();
|
||||
virtual void snap(frame_data_info info);
|
||||
virtual cv::Size frame_data_size();
|
||||
virtual void stopsnap();
|
||||
virtual int getautosizeheight();
|
||||
virtual void set_size(int width, int height);
|
||||
virtual void set_sp(int sp);
|
||||
|
||||
virtual void *readFrame(int timeout);
|
||||
virtual frame_data_info ReadMultiFrame(int state);
|
||||
virtual void set_gain(int ix, int val);
|
||||
virtual void set_offset(int ix, int val);
|
||||
virtual void set_expo(int ix, int val);
|
||||
|
||||
virtual std::shared_ptr<IRegsAccess> regs();
|
||||
virtual void reset();
|
||||
virtual int width();
|
||||
virtual int height();
|
||||
virtual int color();
|
||||
virtual void init_autocorrect(int colormode);
|
||||
virtual void setcapturecall(std::function<void(int, std::string)> callback)
|
||||
{
|
||||
m_captureCallback = callback;
|
||||
};
|
||||
virtual void Fpga_regsAccess_reset(bool enable);
|
||||
virtual uint32_t multi_frame_counts() { return frame_count; }
|
||||
virtual uint32_t multi_curr_snap_index() { return curr_frame_snap_index; }
|
||||
virtual void single_correct(std::uint32_t mode);
|
||||
virtual cv::Mat read_one_frame() override;
|
||||
cv::Mat merge_8478(cv::Mat src, bool color, uint32_t version);
|
||||
|
||||
void init_imagedatabuffer();
|
||||
void free_imagedatabuffer();
|
||||
void update_imgdatainfo(void *itemmat, frame_data_info &info, uint32_t h, uint32_t w);
|
||||
void update_imgdatainfo(void *itemmat, uint32_t h, uint32_t w);
|
||||
|
||||
private:
|
||||
void configFPGAParam(int mode, int dpi);
|
||||
void configFPGAParam_digital_gain(int mode, int dpi);
|
||||
void init_lutdate();
|
||||
void openDevice(int dpi, int mode);
|
||||
void creatcorrectconfig(int dpi, int mode);
|
||||
bool saveLutImg(int dpi, int mode, bool black);
|
||||
void correctcolor(int correctmode);
|
||||
void fpga_reset();
|
||||
void fpga_reload();
|
||||
public:
|
||||
// 8478 寄存器设置函数
|
||||
void set_ADC_config_frequency(uint32_t freq);
|
||||
void init_adc_8478();
|
||||
void write_adc_8478(int bank, int addr, int val, bool A_or_B);
|
||||
void write_adc_8478(int bank, int addr, int val_A, int val_B);
|
||||
void write_adc_8478(std::vector<std::tuple<int,int,int,int>> maps);
|
||||
uint32_t read_adc_8478(int bank, int addr, bool A_or_B);
|
||||
void set_exp_8478_single(int exp_r, int exp_g, int exp_b, int sp, bool A_or_B, bool is_gray);
|
||||
void set_led_off();
|
||||
void set_pixel_count_8478(int val, bool is_gray);
|
||||
void set_digital_offset_8478(int channel, int val_A, int val_B, int color);
|
||||
void set_digital_gain_8478(int channel, uint8_t val_A, uint8_t val_B, int color);
|
||||
void set_dpi_mode(bool is_600);
|
||||
void set_BOS_postion(uint32_t rise, uint32_t fall);
|
||||
void set_EN_postion(uint32_t rise, uint32_t fall);
|
||||
void set_7864A_current_ctrl(uint32_t current);
|
||||
void set_LED_PTN_8478(bool is_bw);
|
||||
|
||||
private:
|
||||
std::function<void(int, std::string)> m_captureCallback;
|
||||
std::shared_ptr<gVideo> video;
|
||||
std::shared_ptr<Gpio> vdd_cis_3voff_pin;
|
||||
std::shared_ptr<Gpio> vdd_vis_5ven_pin;
|
||||
std::shared_ptr<Gpio> reset_pin;
|
||||
std::shared_ptr<Gpio> image_in_transfer_pin;
|
||||
std::shared_ptr<Gpio> initDone_pin;
|
||||
std::shared_ptr<Gpio> fpgaLoad;
|
||||
std::shared_ptr<FpgaComm> fpgaComm;
|
||||
std::shared_ptr<Gpio> fpga_conf_initn;
|
||||
std::shared_ptr<Gpio> fpga_conf_done;
|
||||
ThreadPool snapthread;
|
||||
uint32_t m_fpgaversion;
|
||||
uint32_t frame_height;
|
||||
uint32_t frame_count;
|
||||
uint32_t curr_frame_snap_index;
|
||||
const int FPGA_MAX_HEIGHT_SUP = 1048576;
|
||||
frame_data_info pimgdata_info;
|
||||
std::future<void> snap_fu;
|
||||
bool bcorrecting;
|
||||
bool b_stop_snap;
|
||||
std::thread m_correctthread;
|
||||
HGScanConfig m_config;
|
||||
FPGAConfigParam_8478 m_fpgaparam;
|
||||
|
||||
const uint8_t bank_value[256] =
|
||||
// {0x15,0x78,0x80,0x90,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //bank 0 32us
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
|
||||
// //0x40,0x40,0x40,0x05,0x46,0x23,0x54,0x62,0x35,0x46,0x23,0x00,0x03,0x04,0x05,0x01, //敦南默认值
|
||||
// 0x40,0x40,0x80,0x03,0x25,0x46,0x32,0x54,0x63,0x25,0x46,0x00,0x03,0x04,0x05,0x01,
|
||||
// 0x01,0x00,0x06,0x06,0x03,0x05,0x00,0x14,0x07,0x0B,0x23,0x27,0x00,0x01,0x00,0x00,
|
||||
|
||||
// 0x35,0x02,0x04,0x02,0x04,0x02,0x04,0x00,0x01,0x02,0x00,0x00,0x00,0x01,0x00,0x01, //bank 1
|
||||
// 0x02,0x00,0x00,0x00,0x01,0x00,0x01,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
// 0x55,0x00,0x41,0x00,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x01, //bank 2
|
||||
// 0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x06,0x00,
|
||||
// 0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
// 0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //bank 3
|
||||
// 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,
|
||||
// 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
|
||||
{0x15, 0x78, 0x80, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // bank 0 64us
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
||||
// 0x40,0x40,0x40,0x05,0x46,0x23,0x54,0x62,0x35,0x46,0x23,0x00,0x03,0x04,0x05,0x01, //敦南默认值
|
||||
0x40, 0x40, 0x80, 0x03, 0x25, 0x46, 0x32, 0x54, 0x63, 0x25, 0x46, 0x00, 0x03, 0x04, 0x05, 0x01,
|
||||
0x01, 0x00, 0x06, 0x06, 0x03, 0x05, 0x00, 0x14, 0x07, 0x0B, 0x24, 0x28, 0x00, 0x01, 0x00, 0x00,
|
||||
// 0x01, 0x00, 0x06, 0x06, 0x03, 0x05, 0x00, 0x14, 0x07, 0x0B, 0x25, 0x29, 0x00, 0x01, 0x00, 0x00,
|
||||
|
||||
0x35, 0x03, 0xdf, 0x03, 0xdf, 0x03, 0xdf, 0x00, 0x01, 0x03, 0xb6, 0x00, 0x00, 0x01, 0x00, 0x01, // bank 1
|
||||
0x03, 0xb6, 0x00, 0x00, 0x01, 0x00, 0x01, 0x03, 0xb6, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x55, 0x00, 0x42, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x03, // bank 2
|
||||
0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // bank 3
|
||||
0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
//.colorSp_200 = 2606 , .graySp_200= 7818,.colorSp_300 = 2804 ,.graySp_300 = 8412,.colorSp_600 = 3405 ,.graySp_600 = 10215
|
||||
|
||||
const uint8_t bank_change[4] = {0x15, 0x35, 0x55, 0x75};
|
||||
union adc_8478_param
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t val_l : 8; // 数据位
|
||||
uint32_t addr_l : 6; // adc 寄存器地址
|
||||
uint32_t r_or_w_l : 2; // 读写标志位 0x11 读 0x01 写 8458 0x10 读 0x00 写 8478
|
||||
uint32_t val_h : 8;
|
||||
uint32_t addr_h : 6;
|
||||
uint32_t r_or_w_h : 2;
|
||||
} param;
|
||||
uint32_t value;
|
||||
};
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,222 @@
|
|||
#pragma once
|
||||
#include "ICapturer.h"
|
||||
#include "ThreadPool.h"
|
||||
class FpgaComm;
|
||||
class gVideo;
|
||||
class Gpio;
|
||||
|
||||
class MultiFrameCapture_8458Color : public ICapturer
|
||||
{
|
||||
public:
|
||||
MultiFrameCapture_8458Color();
|
||||
virtual ~MultiFrameCapture_8458Color();
|
||||
virtual void open();
|
||||
virtual void open(HGScanConfig config,FPGAConfigParam fpgaparam);
|
||||
virtual void open(HGScanConfig config, FPGAConfigParam_8478 fpgaparam){}
|
||||
virtual void close();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool is_runing();
|
||||
virtual void snap();
|
||||
virtual void snap(frame_data_info info);
|
||||
virtual cv::Size frame_data_size();
|
||||
virtual void stopsnap();
|
||||
virtual int getautosizeheight();
|
||||
virtual void set_size(int width, int height);
|
||||
virtual void set_sp(int sp);
|
||||
|
||||
virtual void *readFrame(int timeout);
|
||||
virtual frame_data_info ReadMultiFrame(int state);
|
||||
virtual void set_gain(int ix, int val);
|
||||
virtual void set_offset(int ix, int val);
|
||||
virtual void set_expo(int ix, int val);
|
||||
|
||||
virtual std::shared_ptr<IRegsAccess> regs();
|
||||
virtual void reset();
|
||||
virtual int width();
|
||||
virtual int height();
|
||||
virtual int color();
|
||||
virtual void init_autocorrect(int colormode);
|
||||
virtual void setcapturecall(std::function<void(int, std::string)> callback)
|
||||
{
|
||||
m_captureCallback = callback;
|
||||
};
|
||||
virtual void Fpga_regsAccess_reset(bool enable);
|
||||
|
||||
virtual uint32_t multi_frame_counts() { return frame_count; }
|
||||
virtual uint32_t multi_curr_snap_index() { return curr_frame_snap_index; }
|
||||
virtual void single_correct(std::uint32_t mode);
|
||||
virtual cv::Mat read_one_frame() override;
|
||||
|
||||
void init_imagedatabuffer();
|
||||
void free_imagedatabuffer();
|
||||
void update_imgdatainfo(void *itemmat, frame_data_info &info, uint32_t h, uint32_t w);
|
||||
void update_imgdatainfo(void *itemmat, uint32_t h, uint32_t w);
|
||||
|
||||
private:
|
||||
void configFPGAParam(int mode, int dpi);
|
||||
void init_lutdate();
|
||||
void openDevice(int dpi, int mode);
|
||||
void creatcorrectconfig(int dpi, int mode);
|
||||
bool saveLutImg(int dpi, int mode, bool black);
|
||||
void correctcolor(int correctmode);
|
||||
|
||||
void fpga_reset();
|
||||
void fpga_reload();
|
||||
|
||||
void init_adc_8458();
|
||||
void write_adc_8458(int bank,int addr,int val,bool A_or_B);
|
||||
uint32_t read_adc_8458(int bank,int addr,bool A_or_B);
|
||||
void set_exp_8458_double(int exp,int sp,bool A_or_B);
|
||||
void set_exp_8458_single(int exp,int sp,bool A_or_B);
|
||||
void set_pixel_count_8458(int val);
|
||||
void set_analog_gain_8458(int r1,int r2,int g1,int g2,int b1,int b2,bool A_or_B);
|
||||
void set_analog_offset_8458(int type,int val,bool A_or_B);
|
||||
void set_digital_offset_8458(int type,int val,bool A_or_B);
|
||||
void set_digital_gain_8458(int type,int val,bool A_or_B);
|
||||
void set_ADC_config_frequency(uint32_t freq);
|
||||
void set_led_off();
|
||||
void set_dpi_mode(bool is_600);
|
||||
|
||||
private:
|
||||
std::function<void(int, std::string)> m_captureCallback;
|
||||
std::shared_ptr<gVideo> video;
|
||||
std::shared_ptr<Gpio> vdd_cis_3voff_pin;
|
||||
std::shared_ptr<Gpio> vdd_vis_5ven_pin;
|
||||
std::shared_ptr<Gpio> reset_pin;
|
||||
std::shared_ptr<Gpio> image_in_transfer_pin;
|
||||
std::shared_ptr<Gpio> initDone_pin;
|
||||
std::shared_ptr<Gpio> fpgaLoad;
|
||||
std::shared_ptr<FpgaComm> fpgaComm;
|
||||
std::shared_ptr<Gpio> fpga_conf_initn;
|
||||
std::shared_ptr<Gpio> fpga_conf_done;
|
||||
ThreadPool snapthread;
|
||||
uint32_t m_fpgaversion;
|
||||
uint32_t frame_height;
|
||||
uint32_t frame_count;
|
||||
uint32_t curr_frame_snap_index;
|
||||
const int FPGA_MAX_HEIGHT_SUP=1048576;
|
||||
frame_data_info pimgdata_info;
|
||||
std::future<void> snap_fu;
|
||||
bool bcorrecting;
|
||||
bool b_stop_snap;
|
||||
std::thread m_correctthread;
|
||||
HGScanConfig m_config;
|
||||
FPGAConfigParam m_fpgaparam;
|
||||
|
||||
const uint8_t bank_value_b[192] =
|
||||
{0x01,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 //300*600 dpi
|
||||
,0x44,0x64,0x46,0x00,0x64,0x00,0x64,0x00,0x64,0x00
|
||||
,0xc8,0x00,0x64,0x00,0xc8,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xA1,0x01
|
||||
,0x44,0x43,0x45,0x09,0x02,0x02,0x02,0x00,0x2A,0x14
|
||||
,0x34,0x05,0x00,0x01,0x13,0xc4,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00
|
||||
,0x41,0x00,0x50,0x09,0xe2,0x0a,0x32,0x13,0xc3,0x00
|
||||
//,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00
|
||||
,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00
|
||||
,0x02,0x00,0x03,0x02,0x00,0x60,0x00,0x6d,0x00,0x60
|
||||
//,0x02,0x00,0x03,0x02,0x00,0x5c,0x00,0x5D,0x00,0x60
|
||||
,0x07,0x8C,0x0A,0x5F,0x00,0x03,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00};
|
||||
|
||||
|
||||
const uint8_t bank_value[192] =
|
||||
// {0x01,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 //300*300 dpi
|
||||
// ,0x44,0x64,0x46,0x00,0x64,0x00,0x64,0x00,0x64,0x00
|
||||
// ,0xc8,0x00,0x64,0x00,0xc8,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xA1,0x01
|
||||
// ,0x44,0x43,0x45,0x09,0x02,0x02,0x02,0x00,0x2A,0x14
|
||||
// ,0x34,0x05,0x00,0x01,0x13,0xc4,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00
|
||||
// ,0x41,0x00,0x50,0x09,0xe2,0x0a,0x32,0x13,0xc3,0x00
|
||||
// //,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00
|
||||
// ,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00
|
||||
// ,0x02,0x00,0x03,0x04,0x00,0x60,0x00,0x6D,0x00,0x60
|
||||
// ,0x07,0x8C,0x0A,0x5F,0x00,0x03,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00};
|
||||
|
||||
// {0x01,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 //300*600 dpi
|
||||
// ,0x44,0x64,0x46,0x00,0x64,0x00,0x64,0x00,0x64,0x00
|
||||
// ,0xc8,0x00,0x64,0x00,0xc8,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xA1,0x01
|
||||
// ,0x44,0x43,0x45,0x09,0x02,0x02,0x02,0x00,0x2A,0x14
|
||||
// ,0x34,0x05,0x00,0x01,0x13,0xc4,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00
|
||||
// ,0x41,0x00,0x50,0x09,0xe2,0x0a,0x32,0x13,0xc3,0x00
|
||||
// //,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00
|
||||
// ,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00
|
||||
// ,0x02,0x00,0x03,0x02,0x00,0x60,0x00,0x6D,0x00,0x60
|
||||
// //,0x02,0x00,0x03,0x02,0x00,0x61,0x00,0x66,0x00,0x60
|
||||
// //,0x02,0x00,0x03,0x02,0x00,0x5c,0x00,0x5D,0x00,0x60
|
||||
// ,0x07,0x8c,0x0A,0x5F,0x00,0x03,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// ,0x00,0x00,0x00,0x00};
|
||||
|
||||
|
||||
{0x01,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 //600*600 dpi
|
||||
,0x44,0x64,0x46,0x00,0x64,0x00,0x64,0x00,0x64,0x00
|
||||
,0xc8,0x00,0x64,0x00,0xc8,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xA1,0x01
|
||||
,0x44,0x43,0x45,0x09,0x02,0x02,0x02,0x00,0x2A,0x14
|
||||
,0x34,0x05,0x00,0x01,0x13,0xc4,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00
|
||||
,0x41,0x00,0x50,0x09,0xe2,0x0a,0x32,0x13,0xc3,0x00
|
||||
//,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00
|
||||
,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00
|
||||
,0x01,0x00,0x01,0x02,0x00,0x60,0x00,0x6D,0x00,0x60
|
||||
//,0x02,0x00,0x03,0x02,0x00,0x5c,0x00,0x5D,0x00,0x60
|
||||
,0x07,0x8C,0x0A,0x5F,0x00,0x03,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
,0x00,0x00,0x00,0x00};
|
||||
|
||||
const uint8_t bank_change[3] = {0x01,0x41,0x81};
|
||||
union adc_8458_param
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t val_l : 8; //数据位
|
||||
uint32_t addr_l : 6; //adc 寄存器地址
|
||||
uint32_t r_or_w_l :2; //读写标志位 0x11 读 0x01 写
|
||||
uint32_t val_h : 8;
|
||||
uint32_t addr_h : 6;
|
||||
uint32_t r_or_w_h :2;
|
||||
}param;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,170 @@
|
|||
#pragma once
|
||||
#include "ICapturer.h"
|
||||
#include "ThreadPool.h"
|
||||
class FpgaComm;
|
||||
class gVideo;
|
||||
class Gpio;
|
||||
|
||||
class MultiFrameCapture_8478_HL : public ICapturer
|
||||
{
|
||||
public:
|
||||
MultiFrameCapture_8478_HL();
|
||||
virtual ~MultiFrameCapture_8478_HL();
|
||||
virtual void open();
|
||||
virtual void open(HGScanConfig config, FPGAConfigParam fpgaparam){};
|
||||
virtual void open(HGScanConfig config, FPGAConfigParam_8478 fpgaparam);
|
||||
virtual void close();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool is_runing();
|
||||
virtual void snap();
|
||||
virtual void snap(frame_data_info info);
|
||||
virtual cv::Size frame_data_size();
|
||||
virtual void stopsnap();
|
||||
virtual int getautosizeheight();
|
||||
virtual void set_size(int width, int height);
|
||||
virtual void set_sp(int sp);
|
||||
|
||||
virtual void *readFrame(int timeout);
|
||||
virtual frame_data_info ReadMultiFrame(int state);
|
||||
virtual void set_gain(int ix, int val);
|
||||
virtual void set_offset(int ix, int val);
|
||||
virtual void set_expo(int ix, int val);
|
||||
|
||||
virtual std::shared_ptr<IRegsAccess> regs();
|
||||
virtual void reset();
|
||||
virtual int width();
|
||||
virtual int height();
|
||||
virtual int color();
|
||||
virtual void init_autocorrect(int colormode);
|
||||
virtual void setcapturecall(std::function<void(int, std::string)> callback)
|
||||
{
|
||||
m_captureCallback = callback;
|
||||
};
|
||||
virtual void Fpga_regsAccess_reset(bool enable);
|
||||
virtual uint32_t multi_frame_counts() { return frame_count; }
|
||||
virtual uint32_t multi_curr_snap_index() { return curr_frame_snap_index; }
|
||||
virtual void single_correct(std::uint32_t mode);
|
||||
virtual cv::Mat read_one_frame() override;
|
||||
cv::Mat merge_8478(cv::Mat src, bool color, uint32_t version);
|
||||
|
||||
void init_imagedatabuffer();
|
||||
void free_imagedatabuffer();
|
||||
void update_imgdatainfo(void *itemmat, frame_data_info &info, uint32_t h, uint32_t w);
|
||||
void update_imgdatainfo(void *itemmat, uint32_t h, uint32_t w);
|
||||
|
||||
private:
|
||||
void configFPGAParam(int mode, int dpi);
|
||||
void configFPGAParam_digital_gain(int mode, int dpi);
|
||||
void init_lutdate();
|
||||
void openDevice(int dpi, int mode);
|
||||
void creatcorrectconfig(int dpi, int mode);
|
||||
bool saveLutImg(int dpi, int mode, bool black);
|
||||
void correctcolor(int correctmode);
|
||||
void fpga_reset();
|
||||
void fpga_reload();
|
||||
public:
|
||||
// 8478 寄存器设置函数
|
||||
void set_ADC_config_frequency(uint32_t freq);
|
||||
void set_cis_type_hl(bool is_hl);
|
||||
void init_adc_8478();
|
||||
void write_adc_8478(int bank, int addr, int val, bool A_or_B);
|
||||
uint32_t read_adc_8478(int bank, int addr, bool A_or_B);
|
||||
void set_exp_8478_single(int exp_r, int exp_g, int exp_b, int sp, bool A_or_B, bool is_gray);
|
||||
void set_led_off();
|
||||
void set_pixel_count_8478(int val, bool is_gray);
|
||||
void set_digital_offset_8478(int channel, int val, bool A_or_B, int color);
|
||||
void set_digital_gain_8478(int channel, uint8_t val, bool A_or_B, int color);
|
||||
void set_dpi_mode(int type);
|
||||
void set_BOS_postion(uint32_t rise, uint32_t fall);
|
||||
void set_EN_postion(uint32_t rise, uint32_t fall);
|
||||
void set_7864A_current_ctrl(uint32_t current);
|
||||
void set_LED_PTN_8478(bool is_bw);
|
||||
|
||||
private:
|
||||
std::function<void(int, std::string)> m_captureCallback;
|
||||
std::shared_ptr<gVideo> video;
|
||||
std::shared_ptr<Gpio> vdd_cis_3voff_pin;
|
||||
std::shared_ptr<Gpio> vdd_vis_5ven_pin;
|
||||
std::shared_ptr<Gpio> reset_pin;
|
||||
std::shared_ptr<Gpio> image_in_transfer_pin;
|
||||
std::shared_ptr<Gpio> initDone_pin;
|
||||
std::shared_ptr<Gpio> fpgaLoad;
|
||||
std::shared_ptr<FpgaComm> fpgaComm;
|
||||
std::shared_ptr<Gpio> fpga_conf_initn;
|
||||
std::shared_ptr<Gpio> fpga_conf_done;
|
||||
ThreadPool snapthread;
|
||||
uint32_t m_fpgaversion;
|
||||
uint32_t frame_height;
|
||||
uint32_t frame_count;
|
||||
uint32_t curr_frame_snap_index;
|
||||
const int FPGA_MAX_HEIGHT_SUP = 1048576;
|
||||
frame_data_info pimgdata_info;
|
||||
std::future<void> snap_fu;
|
||||
bool bcorrecting;
|
||||
bool b_stop_snap;
|
||||
std::thread m_correctthread;
|
||||
HGScanConfig m_config;
|
||||
FPGAConfigParam_8478 m_fpgaparam;
|
||||
|
||||
const uint8_t bank_value[256] =
|
||||
// {0x15,0x78,0x80,0x90,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //bank 0 32us
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
|
||||
// //0x40,0x40,0x40,0x05,0x46,0x23,0x54,0x62,0x35,0x46,0x23,0x00,0x03,0x04,0x05,0x01, //敦南默认值
|
||||
// 0x40,0x40,0x80,0x03,0x25,0x46,0x32,0x54,0x63,0x25,0x46,0x00,0x03,0x04,0x05,0x01,
|
||||
// 0x01,0x00,0x06,0x06,0x03,0x05,0x00,0x14,0x07,0x0B,0x23,0x27,0x00,0x01,0x00,0x00,
|
||||
|
||||
// 0x35,0x02,0x04,0x02,0x04,0x02,0x04,0x00,0x01,0x02,0x00,0x00,0x00,0x01,0x00,0x01, //bank 1
|
||||
// 0x02,0x00,0x00,0x00,0x01,0x00,0x01,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
// 0x55,0x00,0x41,0x00,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x01, //bank 2
|
||||
// 0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x06,0x00,
|
||||
// 0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
// 0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //bank 3
|
||||
// 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,
|
||||
// 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
|
||||
{0x15, 0x78, 0x80, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // bank 0 64us
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
||||
// 0x40,0x40,0x40,0x05,0x46,0x23,0x54,0x62,0x35,0x46,0x23,0x00,0x03,0x04,0x05,0x01, //敦南默认值
|
||||
0x40, 0x40, 0x80, 0x03, 0x25, 0x46, 0x32, 0x54, 0x63, 0x25, 0x46, 0x00, 0x03, 0x04, 0x05, 0x01,
|
||||
0x01, 0x00, 0x06, 0x00, 0x05, 0x03, 0x00, 0x14, 0x07, 0x0B, 0x24, 0x28, 0x00, 0x01, 0x00, 0x00,
|
||||
// 0x01, 0x00, 0x06, 0x06, 0x03, 0x05, 0x00, 0x14, 0x07, 0x0B, 0x25, 0x29, 0x00, 0x01, 0x00, 0x00,
|
||||
|
||||
0x35, 0x03, 0xdf, 0x03, 0xdf, 0x03, 0xdf, 0x00, 0x01, 0x03, 0xb6, 0x00, 0x00, 0x01, 0x00, 0x01, // bank 1
|
||||
0x03, 0xb6, 0x00, 0x00, 0x01, 0x00, 0x01, 0x03, 0xb6, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x55, 0x00, 0x54, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x03, // bank 2
|
||||
0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // bank 3
|
||||
0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
//.colorSp_200 = 2606 , .graySp_200= 7818,.colorSp_300 = 2804 ,.graySp_300 = 8412,.colorSp_600 = 3405 ,.graySp_600 = 10215
|
||||
|
||||
const uint8_t bank_change[4] = {0x15, 0x35, 0x55, 0x75};
|
||||
union adc_8478_param
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t val_l : 8; // 数据位
|
||||
uint32_t addr_l : 6; // adc 寄存器地址
|
||||
uint32_t r_or_w_l : 2; // 读写标志位 0x11 读 0x01 写 8458 0x10 读 0x00 写 8478
|
||||
uint32_t val_h : 8;
|
||||
uint32_t addr_h : 6;
|
||||
uint32_t r_or_w_h : 2;
|
||||
} param;
|
||||
uint32_t value;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,182 @@
|
|||
#pragma once
|
||||
#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;
|
||||
static void get_system_output(char *cmd, char *output, int size)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
fp = popen(cmd, "r");
|
||||
if (fp)
|
||||
{
|
||||
if (fgets(output, size, fp) != NULL)
|
||||
{
|
||||
if (output[strlen(output) - 1] == '\n')
|
||||
output[strlen(output) - 1] = '\0';
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
/*block to kbyte*/
|
||||
static unsigned long kscale(unsigned long m_block, unsigned long m_kbyte)
|
||||
{
|
||||
|
||||
return ((unsigned long long)m_block * m_kbyte + 1024 / 2) / 1024;
|
||||
}
|
||||
|
||||
/*convert size to GB MB KB*/
|
||||
static void convert_size(float m_size, int *dest)
|
||||
{
|
||||
if ((((m_size / 1024.0) / 1024.0)) >= 1.0)
|
||||
{
|
||||
*dest = (int)((m_size / 1024.0) / 1024.0);
|
||||
}
|
||||
else if ((m_size / 1024.0) >= 1.0)
|
||||
{
|
||||
*dest = (int)(m_size / 1024);
|
||||
}
|
||||
}
|
||||
|
||||
SysInforTool::SysInforTool(ScannerSysInfo tinfo)
|
||||
{
|
||||
m_sysinfo = tinfo;
|
||||
}
|
||||
|
||||
SysInforTool::~SysInforTool()
|
||||
{
|
||||
}
|
||||
|
||||
/*获取文件系统信息*/
|
||||
int SysInforTool::get_fileSystem_info(const char *fileSystem_name, struct fileSystem_info *fi)
|
||||
{
|
||||
struct statfs buf;
|
||||
float fileSystem_total_size = 0;
|
||||
float fileSystem_free_size = 0;
|
||||
|
||||
if (statfs(fileSystem_name, &buf))
|
||||
{
|
||||
fprintf(stderr, "statfs %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (buf.f_type)
|
||||
{
|
||||
case 0xEF51:
|
||||
case 0xEF53:
|
||||
sprintf(fi->fileSystem_format, "EXT");
|
||||
break;
|
||||
|
||||
case 0x4d44:
|
||||
sprintf(fi->fileSystem_format, "FAT");
|
||||
break;
|
||||
|
||||
case 0x5346544e:
|
||||
sprintf(fi->fileSystem_format, "NIFS");
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(fi->fileSystem_format, "unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
// bzero(&fi->fileSystem_total_capacity,sizeof(fi->fileSystem_total_capacity));
|
||||
// bzero(&fi->fileSystem_free_capacity,sizeof(fi->fileSystem_free_capacity));
|
||||
|
||||
printf("blocks %ld\n", buf.f_blocks);
|
||||
printf("bfree %ld\n", buf.f_bfree);
|
||||
printf("bsize %ld\n", buf.f_bsize);
|
||||
|
||||
fileSystem_total_size =
|
||||
(float)(kscale(buf.f_blocks, buf.f_bsize));
|
||||
fileSystem_free_size =
|
||||
(float)(kscale(buf.f_bfree, buf.f_bsize));
|
||||
|
||||
printf("total %f\n", fileSystem_total_size);
|
||||
printf("free %f\n", fileSystem_free_size);
|
||||
|
||||
fi->fileSystem_total_capacity = fileSystem_total_size;
|
||||
fi->fileSystem_free_capacity = fileSystem_free_size;
|
||||
// convert_size(fileSystem_total_size,(int*)(&fi->fileSystem_total_capacity));
|
||||
// convert_size(fileSystem_free_size,(int*)(&fi->fileSystem_free_capacity));
|
||||
|
||||
bzero(fi->fileSystem_permissions, sizeof(fi->fileSystem_permissions));
|
||||
sprintf(fi->fileSystem_permissions, "rw");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string SysInforTool::GetSysInfo()
|
||||
{
|
||||
struct sysinfo memInfo;
|
||||
sysinfo(&memInfo);
|
||||
m_sysinfo.MemTotal = memInfo.totalram;
|
||||
fileSystem_info fileinfo;
|
||||
get_fileSystem_info("/", &fileinfo);
|
||||
m_sysinfo.DiskTotal = fileinfo.fileSystem_total_capacity; // KB
|
||||
m_sysinfo.DiskUsed = fileinfo.fileSystem_free_capacity; // KB
|
||||
|
||||
struct utsname t_uname;
|
||||
if (uname(&t_uname) != 0)
|
||||
perror("uname doesn't return 0, so there is an error");
|
||||
|
||||
printf("System Name = %s\n", t_uname.sysname);
|
||||
printf("Node Name = %s\n", t_uname.nodename);
|
||||
printf("Version = %s\n", t_uname.version);
|
||||
printf("Release = %s\n", t_uname.release);
|
||||
printf("Machine = %s\n", t_uname.machine);
|
||||
if (strcmp(t_uname.nodename, "linaro-alip") == 0 && strcmp(t_uname.machine, "armv7l") == 0)
|
||||
{
|
||||
m_sysinfo.Systype = SysType::Sys_Linux_Debian;
|
||||
m_sysinfo.CPU = SCPU::CPU_3288;
|
||||
printf("Machine = %s CPU = %s \n", "Sys_Linux_Debian", "CPU_3288");
|
||||
}
|
||||
else if (strcmp(t_uname.nodename, "linaro-alip") == 0 && strcmp(t_uname.machine, "aarch64") == 0)
|
||||
{
|
||||
m_sysinfo.Systype = SysType::Sys_Linux_Debian;
|
||||
m_sysinfo.CPU = SCPU::CPU_3399;
|
||||
printf("Machine = %s CPU = %s \n", "Sys_Linux_Debian", "CPU_3399");
|
||||
}
|
||||
m_sysinfo.Cistype = HGCISType::CIS_DUNNAN_MONO_V0;
|
||||
m_sysinfo.MtType = SMBType::MB_DRV_ANLU;
|
||||
char output[512];
|
||||
get_system_output("uname -a", output, sizeof(output));
|
||||
std::string ver(output);
|
||||
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;
|
||||
o.close();
|
||||
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,28 @@
|
|||
#pragma once
|
||||
#include "scannersysinfo.h"
|
||||
#include "json.hpp"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
struct fileSystem_info
|
||||
{
|
||||
char fileSystem_format[8];
|
||||
unsigned int fileSystem_total_capacity;
|
||||
unsigned int fileSystem_free_capacity;
|
||||
char fileSystem_permissions[3];
|
||||
};
|
||||
|
||||
class SysInforTool
|
||||
{
|
||||
public:
|
||||
SysInforTool(ScannerSysInfo tinfo);
|
||||
~SysInforTool();
|
||||
std::string GetSysInfo();
|
||||
|
||||
private:
|
||||
int get_fileSystem_info(const char *fileSystem_name, struct fileSystem_info *fi);
|
||||
void struct2json(json &j, ScannerSysInfo &info);
|
||||
|
||||
private:
|
||||
ScannerSysInfo m_sysinfo;
|
||||
};
|
|
@ -0,0 +1,658 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "correct_ultis.h"
|
||||
#include "CorrectParam.h"
|
||||
#include "commondef.h"
|
||||
#define USE_NEWFLAT
|
||||
using namespace cv;
|
||||
|
||||
void initStep()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
expStep[i][j] = 600;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
offsetStep[i] = 256;
|
||||
printf("offsetStep[%d]=%d \n", i, offsetStep[i]);
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat extractRepresentRow2(const cv::Mat &src)
|
||||
{
|
||||
cv::Mat BWbalenceSrc(1, src.cols * src.channels(), CV_8UC1);
|
||||
|
||||
cv::Mat temp_imageBW(src.rows, src.cols * src.channels(), CV_8UC1, src.data);
|
||||
|
||||
for (size_t i = 0; i < BWbalenceSrc.cols; i++)
|
||||
BWbalenceSrc.at<uchar>(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
|
||||
channel = 408;
|
||||
#endif
|
||||
cv::Mat lut(step / channel, 256, CV_8UC(channel));
|
||||
memcpy(lut.data, dataFile.data, total);
|
||||
return lut;
|
||||
}
|
||||
|
||||
void initLut(const std::string lutpath, bool iscolor)
|
||||
{
|
||||
printf("\n-----init lutpath =%s------------", lutpath.c_str());
|
||||
lutColorMat.release();
|
||||
lutGrayMat.release();
|
||||
|
||||
if (!lutpath.empty() && (access(lutpath.c_str(), F_OK) == 0))
|
||||
{
|
||||
printf("\n %s", lutpath.c_str());
|
||||
if (iscolor)
|
||||
lutColorMat = loadLUT(lutpath); // 彩色校正值
|
||||
else
|
||||
lutGrayMat = loadLUT(lutpath); // 灰色校正值
|
||||
}
|
||||
}
|
||||
|
||||
void correctColor(cv::Mat &src, int dpi, int mode, bool isText, int is_8478)
|
||||
{
|
||||
cv::Mat lutMat;
|
||||
std::string path;
|
||||
if (src.type() == CV_8UC3)
|
||||
{
|
||||
if (lutColorMat.empty())
|
||||
{
|
||||
if (is_8478 == 1)
|
||||
{
|
||||
FPGAConfigParam_8478 param = Get_Static_CorrectParam().GetFpgaparam_8478(dpi, mode);
|
||||
path = isText ? param.TextLutPath : param.LutPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
FPGAConfigParam param = GetFpgaparam(dpi, mode);
|
||||
path = isText ? param.TextLutPath : param.LutPath;
|
||||
}
|
||||
printf("\n %s", path.c_str());
|
||||
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 (is_8478 == 1)
|
||||
{
|
||||
FPGAConfigParam_8478 param = Get_Static_CorrectParam().GetFpgaparam_8478(dpi, mode);
|
||||
path = isText ? param.TextLutPath : param.LutPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
FPGAConfigParam param = GetFpgaparam(dpi, mode);
|
||||
path = isText ? param.TextLutPath : param.LutPath;
|
||||
}
|
||||
printf("\n %s", path.c_str());
|
||||
if (access(path.c_str(), F_OK) != -1)
|
||||
{
|
||||
lutGrayMat = loadLUT(path);
|
||||
// brightness(lutGrayMat);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("error error error %s NOT FOUND", path.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
lutMat = lutGrayMat;
|
||||
}
|
||||
if (lutMat.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cv::Mat image_temp(src.rows, src.cols * src.channels() / lutMat.channels(), CV_8UC(lutMat.channels()), src.data);
|
||||
|
||||
for (size_t i = 0; i < image_temp.cols; i++)
|
||||
cv::LUT(image_temp(cv::Rect(i, 0, 1, image_temp.rows)), lutMat(cv::Rect(0, i, 256, 1)), image_temp(cv::Rect(i, 0, 1, image_temp.rows)));
|
||||
}
|
||||
|
||||
void creatLUTData(int dpi, int mode, FPGAConfigParam param)
|
||||
{
|
||||
printf("eneter creatLUTData \n");
|
||||
auto colormode = mode == 1 ? IMREAD_COLOR : IMREAD_GRAYSCALE;
|
||||
std::string blackPath = param.Flat_BwPath;
|
||||
std::string whitePath = param.Flat_WhitePath;
|
||||
std::string lutsavePath = param.LutPath;
|
||||
cv::Mat lut;
|
||||
cv::Mat twMat = cv::imread(whitePath, IMREAD_ANYCOLOR);
|
||||
cv::Mat tbMat = cv::imread(blackPath, IMREAD_ANYCOLOR);
|
||||
cv::Mat wMat, bMat;
|
||||
if (mode == 1)
|
||||
{
|
||||
wMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, twMat.data);
|
||||
bMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, tbMat.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
wMat = twMat;
|
||||
bMat = tbMat;
|
||||
}
|
||||
|
||||
// lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), dpi, mode); // add by liuyong: 刘丁维提供 2019/4/12
|
||||
lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat), false);
|
||||
// Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1);
|
||||
// memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256);
|
||||
cv::imwrite(param.LutPath, lut);
|
||||
system(("cp -f " + param.LutPath + " " + param.LutPath + "-back").c_str());
|
||||
lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat), true);
|
||||
cv::imwrite(param.TextLutPath, lut);
|
||||
system(("cp -f " + param.TextLutPath + " " + param.TextLutPath + "-back").c_str());
|
||||
printf("exit creatLUTData \n");
|
||||
}
|
||||
|
||||
void creatLUTData_gray(int dpi, int mode, FPGAConfigParam param)
|
||||
{
|
||||
printf("eneter creatLUTData_gray \n");
|
||||
auto colormode = mode == 1 ? IMREAD_COLOR : IMREAD_GRAYSCALE;
|
||||
std::string blackPath = param.Flat_BwPath;
|
||||
std::string whitePath = param.Flat_WhitePath;
|
||||
std::string lutsavePath = param.LutPath;
|
||||
cv::Mat lut;
|
||||
cv::Mat twMat = cv::imread(whitePath, IMREAD_ANYCOLOR);
|
||||
cv::Mat tbMat = cv::imread(blackPath, IMREAD_ANYCOLOR);
|
||||
cv::Mat tw_dynamic = cv::imread(param.Flat_WhitePath.substr(0, param.Flat_WhitePath.length() - 4) + "_dynamic.bmp");
|
||||
cv::Mat wMat, bMat, w_dynamic;
|
||||
if (twMat.empty() && tbMat.empty())
|
||||
return;
|
||||
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;
|
||||
}
|
||||
if (!tw_dynamic.empty())
|
||||
{
|
||||
w_dynamic = mode == 1 ? cv::Mat(tw_dynamic.rows, tw_dynamic.cols * 3, CV_8UC1, tw_dynamic.data) : tw_dynamic;
|
||||
std::vector<cv::Mat> w;
|
||||
w.push_back(colMean(bMat));
|
||||
w.push_back(colMean(wMat));
|
||||
w.push_back(colMean(w_dynamic));
|
||||
lut = calcLUT_gray(w);
|
||||
}
|
||||
else
|
||||
lut = calcLUT_gray(bMat, wMat);
|
||||
// lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), dpi, mode); // add by liuyong: 刘丁维提供 2019/4/12
|
||||
|
||||
cv::imwrite(param.LutPath, lut);
|
||||
// lut = calcLUT_gray(bMat,wMat);
|
||||
// cv::imwrite(param.TextLutPath, lut);
|
||||
printf("exit creatLUTData_gray \n");
|
||||
}
|
||||
|
||||
void creatLUTData(int dpi, int mode, FPGAConfigParam_8478 param)
|
||||
{
|
||||
FPGAConfigParam tmp_{};
|
||||
tmp_.Flat_BwPath = param.Flat_BwPath;
|
||||
tmp_.Flat_WhitePath = param.Flat_WhitePath;
|
||||
tmp_.LutPath = param.LutPath;
|
||||
tmp_.TextLutPath = param.TextLutPath;
|
||||
creatLUTData(dpi, mode, tmp_);
|
||||
}
|
||||
|
||||
void creatLUTData_gray(int dpi, int mode, FPGAConfigParam_8478 param)
|
||||
{
|
||||
FPGAConfigParam tmp_{};
|
||||
tmp_.Flat_BwPath = param.Flat_BwPath;
|
||||
tmp_.Flat_WhitePath = param.Flat_WhitePath;
|
||||
tmp_.LutPath = param.LutPath;
|
||||
tmp_.TextLutPath = param.TextLutPath;
|
||||
creatLUTData_gray(dpi, mode, tmp_);
|
||||
}
|
||||
|
||||
void creatLUTData(int dpi, int mode)
|
||||
{
|
||||
printf("eneter creatLUTData \n");
|
||||
auto param = GetFpgaparam(dpi, mode);
|
||||
auto colormode = mode == 1 ? IMREAD_COLOR : IMREAD_GRAYSCALE;
|
||||
std::string blackPath = param.Flat_BwPath;
|
||||
std::string whitePath = param.Flat_WhitePath;
|
||||
std::string lutsavePath = param.LutPath;
|
||||
cv::Mat lut;
|
||||
cv::Mat twMat = cv::imread(whitePath, IMREAD_ANYCOLOR);
|
||||
cv::Mat tbMat = cv::imread(blackPath, IMREAD_ANYCOLOR);
|
||||
cv::Mat wMat, bMat;
|
||||
if (twMat.empty() && tbMat.empty())
|
||||
return;
|
||||
if (mode == 1)
|
||||
{
|
||||
wMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, twMat.data);
|
||||
bMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, tbMat.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
wMat = twMat;
|
||||
bMat = tbMat;
|
||||
}
|
||||
|
||||
// lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), dpi, mode); // add by liuyong: 刘丁维提供 2019/4/12
|
||||
lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat), false);
|
||||
// Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1);
|
||||
// memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256);
|
||||
cv::imwrite(param.LutPath, lut);
|
||||
lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat), true);
|
||||
cv::imwrite(param.TextLutPath, lut);
|
||||
printf("exit creatLUTData \n");
|
||||
}
|
||||
|
||||
FPGAConfigParam GetFpgaparam(int dpi, int mode)
|
||||
{
|
||||
FPGAConfigParam param = Get_Static_CorrectParam().GetFpgaparam(dpi, mode);
|
||||
return param;
|
||||
}
|
||||
|
||||
void SaveFpgaparam(FPGAConfigParam ¶m)
|
||||
{
|
||||
Get_Static_CorrectParam().SaveCorrectParam(param);
|
||||
}
|
||||
|
||||
cv::Mat colMean(const cv::Mat &image)
|
||||
{
|
||||
cv::Mat meanMat(1, image.step, CV_8UC1);
|
||||
cv::Mat tempMat(image.rows, image.step, CV_8UC1, image.data);
|
||||
for (int i = 0; i < tempMat.step; i++)
|
||||
meanMat.data[i] = cv::mean(tempMat(cv::Rect(i, 0, 1, tempMat.rows)))[0];
|
||||
|
||||
return meanMat;
|
||||
}
|
||||
|
||||
float gamma(float value, float ex)
|
||||
{
|
||||
return cv::pow(value / 255.0f, 1.0f / ex) * 255.0f + 0.5f;
|
||||
}
|
||||
|
||||
#define GAMMA_EX 1.7f
|
||||
#define BLACK_OFFSET 5
|
||||
void fittingLUT(const std::vector<uchar> &points, uchar min_value, uchar max_value, uchar *data)
|
||||
{
|
||||
float step = max_value - min_value + 1;
|
||||
memset(data, min_value, 127);
|
||||
memset(data + 127, max_value, 129);
|
||||
int b = points[0];
|
||||
int w = points[1];
|
||||
int tb = min_value;
|
||||
int tw = max_value;
|
||||
|
||||
step = cv::max((float)(tw - tb + 1) / (float)(w - b + 1), 0.0f);
|
||||
float temp;
|
||||
for (int j = 0, length = (255 - b + 1); j < length; j++)
|
||||
{
|
||||
temp = gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET;
|
||||
data[j + b] = cv::min(255, cv::max(0, static_cast<int>(temp)));
|
||||
}
|
||||
}
|
||||
|
||||
void fittingLUT_gray(const std::vector<uchar> &points, uchar min_value, uchar max_value, uchar *data)
|
||||
{
|
||||
float step = max_value - min_value + 1;
|
||||
memset(data, min_value, 127);
|
||||
memset(data + 127, max_value, 129);
|
||||
int b = points[0];
|
||||
int w = points[1];
|
||||
int tb = min_value;
|
||||
int tw = max_value;
|
||||
|
||||
step = cv::max((float)(tw - tb + 1) / (float)(w - b + 1), 0.0f);
|
||||
float temp;
|
||||
for (int j = 0, length = (255 - b + 1); j < length; j++)
|
||||
{
|
||||
#if 0
|
||||
temp = gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET;
|
||||
#else
|
||||
temp = tb + step * j;
|
||||
#endif
|
||||
data[j + b] = cv::min(255, cv::max(0, static_cast<int>(temp)));
|
||||
}
|
||||
}
|
||||
|
||||
#define CHANNEL 408
|
||||
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 splitJoint(const cv::Mat &staticMat, const cv::Mat &dynamicsMat)
|
||||
{
|
||||
cv::Mat dst(1, staticMat.cols, staticMat.type());
|
||||
|
||||
uchar *ptr_dst = dst.data;
|
||||
uchar *ptr_mat1 = staticMat.data;
|
||||
uchar *ptr_mat2 = dynamicsMat.data;
|
||||
|
||||
int offset = staticMat.step * 25 / 1000;
|
||||
cv::Range range1(offset, staticMat.step / 2 - offset);
|
||||
cv::Range range2(staticMat.step / 2 + offset, staticMat.step - offset);
|
||||
for (size_t i = 0; i < dst.step; i++)
|
||||
{
|
||||
// if (i < range1.start || i > range2.end || (i > range1.end && i < range2.start))
|
||||
if (ptr_mat1[i] > ptr_mat2[i] + 50)
|
||||
ptr_dst[i] = ptr_mat1[i];
|
||||
else
|
||||
ptr_dst[i] = ptr_mat2[i];
|
||||
// else
|
||||
// ptr_dst[i] = ptr_mat2[i];
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
cv::Mat calcLUT_gray(const cv::Mat &black, const cv::Mat &white)
|
||||
{
|
||||
std::vector<cv::Mat> w;
|
||||
w.push_back(colMean(black));
|
||||
w.push_back(colMean(white));
|
||||
cv::Mat lut = createLUT_gray(w);
|
||||
|
||||
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;
|
||||
|
||||
// std::vector<cv::Mat> w;
|
||||
// w.push_back(colMean(black));
|
||||
// w.push_back(colMean(white));
|
||||
// if(!dynamic.empty())
|
||||
// w.push_back(colMean(dynamic));
|
||||
// if (w.size() == 3)
|
||||
// {
|
||||
// cv::Mat newWhite = splitJoint(w[1], w[2]);
|
||||
// w.erase(w.end() - 1);
|
||||
// w[1] = newWhite;
|
||||
// }
|
||||
|
||||
// cv::Mat lut = createLUT_gray(w);
|
||||
|
||||
// int channel = (lut.rows % CHANNEL == 0) ? CHANNEL : 459;
|
||||
// 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 calcLUT_gray(std::vector<cv::Mat> &w)
|
||||
{
|
||||
if (w.size() == 3)
|
||||
{
|
||||
cv::Mat newWhite = splitJoint(w[1], w[2]);
|
||||
w.erase(w.end() - 1);
|
||||
w[1] = newWhite;
|
||||
// cv::imwrite("/home/test.bmp",newWhite);
|
||||
}
|
||||
|
||||
cv::Mat lut = createLUT_gray(w);
|
||||
|
||||
int channel = (lut.rows % CHANNEL == 0) ? CHANNEL : 459;
|
||||
for (size_t i = 0, block = lut.rows / channel; i < block; i++)
|
||||
{
|
||||
cv::Mat lutROI = lut(cv::Rect(0, i * channel, 256, channel));
|
||||
cv::Mat tran;
|
||||
cv::transpose(lutROI, tran);
|
||||
memcpy(lutROI.data, tran.data, tran.total());
|
||||
}
|
||||
return lut;
|
||||
}
|
||||
|
||||
cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, int dpi, bool colormode)
|
||||
{
|
||||
#ifndef USE_NEWFLAT
|
||||
if (black.empty() || white.empty() || black.channels() != 1 || white.channels() != 1 || black.step != white.step)
|
||||
return cv::Mat();
|
||||
|
||||
int channel = 1;
|
||||
if (black.step == 4896 || black.step == 7344)
|
||||
channel = 408;
|
||||
else if (black.step == 14688 || black.step == 22032 || black.step == 44064)
|
||||
channel = 432; // 486
|
||||
|
||||
if (channel == 1)
|
||||
return cv::Mat();
|
||||
|
||||
const int rows = black.cols / channel;
|
||||
const int cols = 256;
|
||||
auto cc = CV_8UC(channel);
|
||||
Mat lut(rows, cols, CV_8UC(channel));
|
||||
const double gain = 255.0 / ((double)Get_Static_CorrectParam().GetFpgaparam(dpi, colormode).MaxBright);
|
||||
for (size_t i = 0; i < rows; i++)
|
||||
{
|
||||
Mat lut_row = lut(cv::Rect(0, i, cols, 1));
|
||||
unsigned char *ptr_buffer = lut_row.data;
|
||||
unsigned char *ptr_black = black.data + i * channel;
|
||||
unsigned char *ptr_white = white.data + i * channel;
|
||||
for (size_t j = 0; j < cols; j++)
|
||||
for (size_t k = 0; k < channel; k++)
|
||||
{
|
||||
if (ptr_black[k] >= ptr_white[k])
|
||||
{
|
||||
ptr_buffer[j * channel + k] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (j <= ptr_black[k])
|
||||
ptr_buffer[j * channel + k] = 0;
|
||||
else if (j >= ptr_white[k])
|
||||
ptr_buffer[j * channel + k] = 255;
|
||||
else
|
||||
{
|
||||
float val = 255.0f * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]) * gain;
|
||||
ptr_buffer[j * channel + k] = (unsigned char)cv::max(0.0f, cv::min(val, 255.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
cv::Mat saveMat(black.step, 256, CV_8UC1, lut.data);
|
||||
return saveMat.clone();
|
||||
#else
|
||||
return calcLUT(black, white, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<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_gray(const std::vector<cv::Mat> &mats)
|
||||
{
|
||||
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<uchar> grayPoints;
|
||||
for (size_t j = 0; j < mats.size(); j++)
|
||||
grayPoints.push_back(mats[j].data[i]);
|
||||
|
||||
fittingLUT_gray(grayPoints, static_cast<uchar>(min_val), static_cast<uchar>(max_val), lut.data + i * 256);
|
||||
}
|
||||
return lut;
|
||||
}
|
||||
|
||||
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<uchar> grayPoints;
|
||||
for (size_t j = 0; j < mats.size(); j++)
|
||||
grayPoints.push_back(mats[j].data[i]);
|
||||
|
||||
fittingLUT(grayPoints, static_cast<uchar>(min_val), static_cast<uchar>(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> points_x = {0, 25, 215, 255}, points_y = {0, 0, 250, 255};
|
||||
// std::vector<double> points_x = {0, 25, 80, 150, 215}, points_y = {0, 0, 80, 170, 255};
|
||||
std::vector<double> coefficient = caculate(points_x, points_y);
|
||||
|
||||
uchar buffer[256];
|
||||
uchar buffer_B[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
// int temp = coefficient[0] * i * i * i *i+ coefficient[1] * i * i*i + coefficient[2] * i*i + coefficient[3]*i+coefficient[4];
|
||||
int temp = coefficient[0] * i * i * i + coefficient[1] * i * i + coefficient[2] * i + coefficient[3];
|
||||
buffer[i] = static_cast<uchar>(cv::min(255, cv::max(0, temp)));
|
||||
}
|
||||
|
||||
coefficient = caculate({0, 25, 220, 255}, {0, 0, 250, 255});
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
// int temp = coefficient[0] * i * i * i *i+ coefficient[1] * i * i*i + coefficient[2] * i*i + coefficient[3]*i+coefficient[4];
|
||||
int temp = coefficient[0] * i * i * i + coefficient[1] * i * i + coefficient[2] * i + coefficient[3];
|
||||
buffer_B[i] = static_cast<uchar>(cv::min(255, cv::max(0, temp)));
|
||||
}
|
||||
|
||||
cv::Mat lut_lut(256, 1, CV_8UC1, buffer);
|
||||
cv::Mat lut_lut_B(256, 1, CV_8UC1, buffer_B);
|
||||
cv::LUT(lut(cv::Rect(0,0,lut.cols,lut.rows/2)), lut_lut, lut(cv::Rect(0,0,lut.cols,lut.rows/2)));
|
||||
cv::LUT(lut(cv::Rect(0,lut.rows/2,lut.cols,lut.rows/2)), lut_lut_B, lut(cv::Rect(0,lut.rows/2,lut.cols,lut.rows/2)));
|
||||
|
||||
// cv::LUT(lut,lut_lut,lut);
|
||||
|
||||
}
|
||||
return lut;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
#include <sstream>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "CameraParam.h"
|
||||
|
||||
static cv::Mat lutGrayMat; // 灰色校正值
|
||||
static cv::Mat lutColorMat; // 彩色校正值
|
||||
static int offsetStep[12];
|
||||
static int expStep[2][3];
|
||||
|
||||
void initStep();
|
||||
|
||||
cv::Mat colMean(const cv::Mat &image);
|
||||
|
||||
cv::Mat calcLUT(const cv::Mat &black, const cv::Mat &white, bool isTextCorrection);
|
||||
|
||||
cv::Mat calcLUT_gray(const cv::Mat &black, const cv::Mat &white);
|
||||
|
||||
cv::Mat calcLUT_gray(std::vector<cv::Mat> &w);
|
||||
|
||||
cv::Mat extractRepresentRow2(const cv::Mat &src);
|
||||
|
||||
void initLut(const std::string lutpath, bool iscolor);
|
||||
|
||||
cv::Mat createLUT(const std::vector<cv::Mat> &mats, bool isTextCorrect);
|
||||
|
||||
cv::Mat createLUT_gray(const std::vector<cv::Mat> &mats);
|
||||
|
||||
void correctColor(cv::Mat &src, int dpi, int mode, bool isText, int is_8478 = 0);
|
||||
|
||||
void creatLUTData(int dpi, int mode);
|
||||
|
||||
void creatLUTData(int dpi, int mode, FPGAConfigParam param);
|
||||
|
||||
void creatLUTData_gray(int dpi, int mode, FPGAConfigParam param);
|
||||
|
||||
void creatLUTData(int dpi, int mode, FPGAConfigParam_8478 param);
|
||||
|
||||
void creatLUTData_gray(int dpi, int mode, FPGAConfigParam_8478 param);
|
||||
|
||||
FPGAConfigParam GetFpgaparam(int dpi, int mode);
|
||||
|
||||
void SaveFpgaparam(FPGAConfigParam ¶m);
|
||||
|
||||
cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, int dpi, bool colormode);
|
|
@ -0,0 +1,127 @@
|
|||
#include "deviceconfig.h"
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <sys/stat.h>
|
||||
#include "commondef.h"
|
||||
#include <unistd.h>
|
||||
|
||||
DeviceConfig m_static_deviceconfig;
|
||||
|
||||
DeviceConfig::DeviceConfig()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DeviceConfig::~DeviceConfig()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DeviceConfig::DeviceParam DeviceConfig::GetParam()
|
||||
{
|
||||
std::lock_guard<std::mutex> lc(m_lock);
|
||||
json tmp = getjson();
|
||||
return json2struct(tmp);
|
||||
}
|
||||
|
||||
void DeviceConfig::SaveParam(DeviceConfig::DeviceParam param)
|
||||
{
|
||||
std::lock_guard<std::mutex> lc(m_lock);
|
||||
auto tmp = struct2json(param);
|
||||
savejson(tmp);
|
||||
}
|
||||
|
||||
json DeviceConfig::struct2json(DeviceConfig::DeviceParam param)
|
||||
{
|
||||
json js;
|
||||
js[token_code] = param.token;
|
||||
js[lock_enable] = param.is_lock;
|
||||
js[gray_correct_enable] = param.gray_param;
|
||||
js[language] = param.language;
|
||||
return js;
|
||||
}
|
||||
|
||||
DeviceConfig::DeviceParam DeviceConfig::json2struct(json js)
|
||||
{
|
||||
bool is_save = false;
|
||||
DeviceConfig::DeviceParam param;
|
||||
if(js[lock_enable].is_boolean())
|
||||
param.is_lock = js[lock_enable];
|
||||
else {
|
||||
param.is_lock = false;
|
||||
is_save = true;
|
||||
}
|
||||
if(js[token_code].is_string())
|
||||
param.token = js[token_code];
|
||||
else{
|
||||
param.token = "null";
|
||||
is_save = true;
|
||||
}
|
||||
if(js[gray_correct_enable].is_number_unsigned())
|
||||
param.gray_param = js[gray_correct_enable];
|
||||
else{
|
||||
is_save = true;
|
||||
param.gray_param = 0;
|
||||
}
|
||||
if(js[language].is_number())
|
||||
param.language = js[language];
|
||||
else{
|
||||
is_save = true;
|
||||
param.language = 0;
|
||||
}
|
||||
if(is_save)
|
||||
savejson(struct2json(param));
|
||||
return param;
|
||||
}
|
||||
|
||||
json DeviceConfig::getdefaultjson()
|
||||
{
|
||||
json m_json;
|
||||
m_json[lock_enable] = false;
|
||||
m_json[token_code] = "null";
|
||||
m_json[gray_correct_enable] = 0;
|
||||
m_json[language] = 0;
|
||||
return m_json;
|
||||
}
|
||||
|
||||
void DeviceConfig::savejson(json js)
|
||||
{
|
||||
//std::lock_guard<std::mutex> lc(m_lock);
|
||||
std::ofstream o(ParamPath);
|
||||
o << std::setw(4) << js <<std::endl;
|
||||
o.flush();
|
||||
o.close();
|
||||
}
|
||||
|
||||
|
||||
json DeviceConfig::getjson()
|
||||
{
|
||||
if(access(JSON_CORRECTDIR_PATH,0) == -1)
|
||||
{
|
||||
auto ret = mkdir(JSON_CORRECTDIR_PATH, 0777);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("make dir failed .path=%s \n", JSON_CORRECTDIR_PATH);
|
||||
}
|
||||
}
|
||||
if (access(ParamPath.c_str(), F_OK) != 0)
|
||||
{
|
||||
auto cfs = getdefaultjson();
|
||||
savejson(cfs);
|
||||
return cfs;
|
||||
}
|
||||
std::ifstream i(ParamPath);
|
||||
auto pos = i.tellg();
|
||||
i.seekg(0, std::ios::end);
|
||||
if (i.tellg() <= 2)
|
||||
{
|
||||
auto cfs = getdefaultjson();
|
||||
savejson(cfs);
|
||||
return cfs;
|
||||
}
|
||||
i.seekg(pos);
|
||||
json m_json;
|
||||
i >> m_json;
|
||||
i.close();
|
||||
return m_json;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
#pragma once
|
||||
#include <json.hpp>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
class DeviceConfig
|
||||
{
|
||||
private:
|
||||
const std::string ParamPath ="/usr/local/huago/deviceconfig.json";
|
||||
const std::string lock_enable = "lockenable";
|
||||
const std::string token_code = "tokencode";
|
||||
const std::string gray_correct_enable = "graycorrectenable";
|
||||
const std::string language = "Language";
|
||||
public:
|
||||
struct DeviceParam
|
||||
{
|
||||
bool is_lock;
|
||||
uint32_t gray_param;
|
||||
uint32_t language;
|
||||
std::string token;
|
||||
};
|
||||
union Gray_Apply
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t en_200_gray : 1;
|
||||
uint32_t en_200_clr : 1;
|
||||
uint32_t en_300_gray : 1;
|
||||
uint32_t en_300_clr : 1;
|
||||
uint32_t en_600_gray : 1;
|
||||
uint32_t en_600_clr : 1;
|
||||
uint32_t en_slow_gray : 1;
|
||||
uint32_t en_slow_clr : 1;
|
||||
uint32_t en_slow_300_gray : 1;
|
||||
uint32_t en_slow_300_clr : 1;
|
||||
uint32_t en_long_Manuscript_200_gray : 1;
|
||||
uint32_t en_long_Manuscript_200_clr : 1;
|
||||
uint32_t en_long_Manuscript_300_gray : 1;
|
||||
uint32_t en_long_Manuscript_300_clr : 1;
|
||||
uint32_t reserved : 18;
|
||||
}Param_Setting;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
DeviceConfig(/* args */);
|
||||
~DeviceConfig();
|
||||
DeviceConfig::DeviceParam GetParam();
|
||||
void SaveParam(DeviceConfig::DeviceParam param);
|
||||
private:
|
||||
json struct2json(DeviceConfig::DeviceParam param);
|
||||
DeviceConfig::DeviceParam json2struct(json js);
|
||||
void savejson(json js);
|
||||
json getjson();
|
||||
json getdefaultjson();
|
||||
std::mutex m_lock;
|
||||
};
|
||||
|
||||
extern DeviceConfig m_static_deviceconfig;
|
||||
|
||||
static DeviceConfig& Get_static_deviceconfig()
|
||||
{
|
||||
return m_static_deviceconfig;
|
||||
}
|
|
@ -0,0 +1,348 @@
|
|||
#include "gvideo.h"
|
||||
#include <iostream>
|
||||
#include <fcntl.h> /* low-level i/o */
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <dlfcn.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include "linux/v4l2-subdev.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <poll.h>
|
||||
#include <malloc.h>
|
||||
|
||||
static const std::string loggername = "gVideo";
|
||||
|
||||
#define LOG_TRACE(...)
|
||||
#define LOG_ERROR printf
|
||||
#define LOG_INFO(...)
|
||||
|
||||
using namespace std;
|
||||
#define CLEAR(x) memset(&(x), 0, sizeof(x))
|
||||
#define LOG printf
|
||||
|
||||
int file_size(const char *filename)
|
||||
{
|
||||
struct stat statbuf;
|
||||
int ret = stat(filename, &statbuf);
|
||||
int size = -1;
|
||||
if (ret == 0)
|
||||
size = statbuf.st_size;
|
||||
return size;
|
||||
}
|
||||
|
||||
gVideo::gVideo()
|
||||
: fd(-1),
|
||||
buffers(0),
|
||||
bStart(false),
|
||||
dev_name("/dev/video3")
|
||||
{
|
||||
}
|
||||
|
||||
gVideo::~gVideo()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void gVideo::set_buf_count(int count)
|
||||
{
|
||||
v4l_buffer_count = count;
|
||||
}
|
||||
|
||||
bool gVideo::is_open()
|
||||
{
|
||||
return fd >= 0;
|
||||
}
|
||||
|
||||
void gVideo::close()
|
||||
{
|
||||
if (is_open())
|
||||
{
|
||||
stop();
|
||||
uninit_device();
|
||||
close_device();
|
||||
}
|
||||
}
|
||||
|
||||
void gVideo::open(int width, int height)
|
||||
{
|
||||
if (is_open())
|
||||
return;
|
||||
|
||||
open_device();
|
||||
if (is_open())
|
||||
{
|
||||
// init_device();
|
||||
set_size(width, height);
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
void gVideo::start()
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(m_lock);
|
||||
if (bStart)
|
||||
return;
|
||||
|
||||
start_capturing();
|
||||
bStart = true;
|
||||
}
|
||||
|
||||
void gVideo::stop()
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(m_lock);
|
||||
if (bStart)
|
||||
{
|
||||
stop_capturing();
|
||||
bStart = false;
|
||||
}
|
||||
}
|
||||
|
||||
void gVideo::grab(int color, bool bcrrect, int timeout, int flatpara)
|
||||
{
|
||||
}
|
||||
|
||||
bool gVideo::hasframe()
|
||||
{
|
||||
return wait(0);
|
||||
}
|
||||
|
||||
bool gVideo::wait(int msTimeout)
|
||||
{
|
||||
pollfd pfd;
|
||||
pfd.fd = this->fd;
|
||||
pfd.events = POLLIN | POLLRDNORM;
|
||||
|
||||
if (poll(&pfd, 1, msTimeout) > 0)
|
||||
return pfd.revents;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void *gVideo::read_frame(int timeout)
|
||||
{
|
||||
if (!wait(timeout))
|
||||
{
|
||||
LOG_TRACE("read frame time out");
|
||||
return 0;
|
||||
}
|
||||
v4l2_buffer buf;
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
if (-1 == ioctl(fd, VIDIOC_DQBUF, &buf))
|
||||
{
|
||||
LOG_ERROR("VIDIOC_DQBUF error!!! index :%d\n", buf.index);
|
||||
return 0;
|
||||
}
|
||||
if (-1 == ioctl(fd, VIDIOC_QBUF, &buf))
|
||||
{
|
||||
LOG_ERROR("VIDIOC_QBUF error!!! index :%d\n", buf.index);
|
||||
return 0;
|
||||
}
|
||||
return buffers[buf.index].start;
|
||||
}
|
||||
|
||||
void gVideo::set_size(int width, int height)
|
||||
{
|
||||
if (!buffers.empty())
|
||||
uninit_device();
|
||||
|
||||
v4l_width = width;
|
||||
v4l_height = height;
|
||||
// v4l_buffer_count = (10*1024*1024) / (v4l_width*v4l_height*3);
|
||||
// v4l_buffer_count = std::max(3, std::min(v4l_buffer_count, 40)); /* to-do */
|
||||
printf("v4l buffer count %d\n", v4l_buffer_count);
|
||||
init_device();
|
||||
}
|
||||
|
||||
void gVideo::stop_capturing(void)
|
||||
{
|
||||
enum v4l2_buf_type type;
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &type))
|
||||
LOG_ERROR("streamo off");
|
||||
}
|
||||
|
||||
unsigned int querybuf_length;
|
||||
void gVideo::start_capturing(void)
|
||||
{
|
||||
enum v4l2_buf_type type;
|
||||
LOG_INFO("start_capturing::querybuf_length = %d.\n", querybuf_length);
|
||||
for (int i = 0; i < n_buffers; ++i)
|
||||
{
|
||||
struct v4l2_buffer buf;
|
||||
CLEAR(buf);
|
||||
buf.index = i;
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
|
||||
if (-1 == ioctl(fd, VIDIOC_QBUF, &buf))
|
||||
LOG_ERROR("VIDIOC_QBUF Error %d", i);
|
||||
else
|
||||
LOG_INFO("VIDIOC_QBUF %d\n", i);
|
||||
}
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (-1 == ioctl(fd, VIDIOC_STREAMON, &type))
|
||||
LOG_ERROR("VIDIOC_STREAMON");
|
||||
}
|
||||
|
||||
void gVideo::uninit_device(void)
|
||||
{
|
||||
if (!buffers.empty())
|
||||
{
|
||||
for (int i = 0; i < buffers.size(); ++i)
|
||||
if (-1 == munmap(buffers[i].start, buffers[i].length))
|
||||
LOG_ERROR("munmap %d error\n", i);
|
||||
|
||||
struct v4l2_requestbuffers req;
|
||||
CLEAR(req);
|
||||
req.count = 0;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
|
||||
if (-1 == ioctl(fd, VIDIOC_REQBUFS, &req))
|
||||
LOG_ERROR("uinit_device VIDIOC_REQBUFS fail\n");
|
||||
|
||||
buffers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void gVideo::init_mmap(void)
|
||||
{
|
||||
struct v4l2_requestbuffers req;
|
||||
int ret;
|
||||
unsigned int length;
|
||||
unsigned int offset;
|
||||
|
||||
CLEAR(req);
|
||||
req.count = v4l_buffer_count;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
LOG_INFO("set v4l_buffer_count = %d\n", req.count);
|
||||
LOG_INFO("set v4l_buffer_type = %d\n", req.type);
|
||||
LOG_INFO("set v4l_buffer_memory = %d\n", req.memory);
|
||||
|
||||
ret = ioctl(fd, VIDIOC_REQBUFS, &req);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_ERROR("Unable to request buffers: %s (%d).\n", strerror(errno), errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO("%s VIDIOC_REQBUFS sucess\n", dev_name.c_str());
|
||||
}
|
||||
LOG_INFO("%u buffers requested.\n", req.count);
|
||||
|
||||
buffers.resize(req.count);
|
||||
if (buffers.empty())
|
||||
LOG_ERROR("Out of memory\n");
|
||||
|
||||
// 7.VIDIOC_QUERYBUF
|
||||
for (n_buffers = 0; n_buffers < req.count; ++n_buffers)
|
||||
{
|
||||
const char *ts_type, *ts_source;
|
||||
struct v4l2_buffer buf;
|
||||
CLEAR(buf);
|
||||
buf.index = n_buffers;
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
ret = ioctl(fd, VIDIOC_QUERYBUF, &buf);
|
||||
if (ret < 0)
|
||||
LOG_ERROR("Unable to query buffer %u: %s (%d).\n", n_buffers, strerror(errno), errno);
|
||||
else
|
||||
LOG_INFO("index %d VIDIOC_QUERYBUF sucess.\n", n_buffers);
|
||||
// mmap
|
||||
unsigned int length;
|
||||
unsigned int offset;
|
||||
length = buf.length;
|
||||
offset = buf.m.offset;
|
||||
LOG_INFO("Buffer %u length = %d.\n", n_buffers, length);
|
||||
LOG_INFO("Buffer %u offset = %d.\n", n_buffers, offset);
|
||||
|
||||
buffers[n_buffers].length = length;
|
||||
buffers[n_buffers].start =
|
||||
mmap(NULL /* start anywhere */,
|
||||
length,
|
||||
PROT_READ | PROT_WRITE /* required */,
|
||||
MAP_SHARED /* recommended */,
|
||||
fd, offset);
|
||||
if (buffers[n_buffers].start == MAP_FAILED)
|
||||
LOG_ERROR("Unable to map buffer %u: %s (%d)\n", n_buffers, strerror(errno), errno);
|
||||
else
|
||||
LOG_INFO("Buffer %u mapped at address %p.\n", n_buffers, buffers[n_buffers].start);
|
||||
}
|
||||
}
|
||||
|
||||
void printCamInfo(int fd)
|
||||
{ // 获取摄像头所支持的分辨率
|
||||
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
struct v4l2_fmtdesc fmt_1;
|
||||
struct v4l2_frmsizeenum frmsize;
|
||||
struct v4l2_frmivalenum frmival;
|
||||
fmt_1.index = 0;
|
||||
fmt_1.type = type;
|
||||
while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt_1) >= 0)
|
||||
{
|
||||
frmsize.pixel_format = fmt_1.pixelformat;
|
||||
frmsize.index = 0;
|
||||
while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0)
|
||||
{
|
||||
// if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE)
|
||||
// LOG_INFO("line:%d %dx%d", __LINE__, frmsize.discrete.width, frmsize.discrete.height);
|
||||
// else if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE)
|
||||
// LOG_INFO("line:%d %dx%d", __LINE__, frmsize.discrete.width, frmsize.discrete.height);
|
||||
frmsize.index++;
|
||||
}
|
||||
fmt_1.index++;
|
||||
}
|
||||
}
|
||||
|
||||
void gVideo::init_device(void)
|
||||
{
|
||||
struct v4l2_capability cap;
|
||||
struct v4l2_format fmt;
|
||||
printCamInfo(fd);
|
||||
if (-1 == ioctl(fd, VIDIOC_QUERYCAP, &cap))
|
||||
{
|
||||
if (EINVAL == errno)
|
||||
LOG_ERROR("%s is no V4L2 device", dev_name.c_str());
|
||||
else
|
||||
LOG_ERROR("VIDIOC_QUERYCAP");
|
||||
}
|
||||
|
||||
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
|
||||
LOG_ERROR("%s is no video capture device", dev_name.c_str());
|
||||
|
||||
if (!(cap.capabilities & V4L2_CAP_STREAMING))
|
||||
LOG_ERROR("%s does not support streaming i/o", dev_name.c_str());
|
||||
|
||||
CLEAR(fmt);
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
fmt.fmt.pix.width = v4l_width;
|
||||
fmt.fmt.pix.height = v4l_height;
|
||||
// LOG_TRACE("v4l2 init_device width:%d, height:%d\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
|
||||
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
|
||||
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||||
|
||||
if (-1 == ioctl(fd, VIDIOC_S_FMT, &fmt))
|
||||
LOG_ERROR("VIDIOC_S_FMT error");
|
||||
init_mmap();
|
||||
}
|
||||
|
||||
void gVideo::close_device(void)
|
||||
{
|
||||
if (-1 == ::close(fd))
|
||||
LOG_ERROR("close");
|
||||
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
void gVideo::open_device(void)
|
||||
{
|
||||
if ((fd = ::open(dev_name.c_str(), O_RDWR /* required */ /*| O_NONBLOCK*/, 0)) == -1)
|
||||
LOG_ERROR("Cannot open %s", dev_name.c_str());
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
class gVideo
|
||||
{
|
||||
public:
|
||||
gVideo();
|
||||
virtual ~gVideo();
|
||||
|
||||
bool is_open();
|
||||
void close();
|
||||
void open(int width, int height);
|
||||
void start();
|
||||
void stop();
|
||||
void grab(int color, bool bcrrect = false, int timeout = 1000, int flatpara = 0);
|
||||
bool hasframe();
|
||||
virtual void *read_frame(int timeout);
|
||||
void set_size(int width, int height);
|
||||
void set_buf_count(int count);
|
||||
|
||||
protected:
|
||||
bool wait(int msTimeout);
|
||||
|
||||
virtual void stop_capturing(void);
|
||||
virtual void start_capturing(void);
|
||||
virtual void uninit_device(void);
|
||||
virtual void init_mmap(void);
|
||||
virtual void init_device(void);
|
||||
void close_device(void);
|
||||
void open_device(void);
|
||||
|
||||
struct buffer
|
||||
{
|
||||
void *start;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
int v4l_buffer_count = 3;
|
||||
int v4l_width = 3100;
|
||||
int v4l_height = 3100;
|
||||
std::string dev_name;
|
||||
int fd;
|
||||
std::vector<buffer> buffers;
|
||||
unsigned int n_buffers;
|
||||
std::mutex m_lock;
|
||||
volatile bool bStart;
|
||||
};
|
|
@ -0,0 +1,918 @@
|
|||
#include "gvideoisp1.h"
|
||||
#include <fcntl.h> /* low-level i/o */
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "linux/videodev2.h"
|
||||
#include "linux/v4l2-subdev.h"
|
||||
#include <dlfcn.h>
|
||||
#include "string.h"
|
||||
#include <iostream>
|
||||
#include <malloc.h>
|
||||
|
||||
#define LOG_TRACE(...)
|
||||
#define LOG_ERROR printf
|
||||
#define LOG_INFO(...)
|
||||
|
||||
static const std::string loggername = "GVideoISP1";
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define CLEAR(x) memset(&(x), 0, sizeof(x))
|
||||
|
||||
#define V4L2_BUF_TYPE_META_OUTPUT 14
|
||||
#define V4L2_CAP_META_OUTPUT 0x08000000 /* Is a metadata output device */
|
||||
|
||||
static struct
|
||||
{
|
||||
enum v4l2_buf_type type;
|
||||
bool supported;
|
||||
const char *name;
|
||||
const char *string;
|
||||
} buf_types[] = {
|
||||
{
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
||||
1,
|
||||
"Video capture mplanes",
|
||||
"capture-mplane",
|
||||
},
|
||||
{
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
|
||||
1,
|
||||
"Video output",
|
||||
"output-mplane",
|
||||
},
|
||||
{
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
1,
|
||||
"Video capture",
|
||||
"capture",
|
||||
},
|
||||
{
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT,
|
||||
1,
|
||||
"Video output mplanes",
|
||||
"output",
|
||||
},
|
||||
{V4L2_BUF_TYPE_VIDEO_OVERLAY, 0, "Video overlay", "overlay"},
|
||||
//{ V4L2_BUF_TYPE_META_CAPTURE, 1, "Meta-data capture", "meta-capture", }//,
|
||||
};
|
||||
|
||||
static struct v4l2_format_info
|
||||
{
|
||||
const char *name;
|
||||
unsigned int fourcc;
|
||||
unsigned char n_planes;
|
||||
} pixel_formats[] = {
|
||||
{"RGB332", V4L2_PIX_FMT_RGB332, 1},
|
||||
{"RGB444", V4L2_PIX_FMT_RGB444, 1},
|
||||
{"ARGB444", V4L2_PIX_FMT_ARGB444, 1},
|
||||
{"XRGB444", V4L2_PIX_FMT_XRGB444, 1},
|
||||
{"RGB555", V4L2_PIX_FMT_RGB555, 1},
|
||||
{"ARGB555", V4L2_PIX_FMT_ARGB555, 1},
|
||||
{"XRGB555", V4L2_PIX_FMT_XRGB555, 1},
|
||||
{"RGB565", V4L2_PIX_FMT_RGB565, 1},
|
||||
{"RGB555X", V4L2_PIX_FMT_RGB555X, 1},
|
||||
{"RGB565X", V4L2_PIX_FMT_RGB565X, 1},
|
||||
{"BGR666", V4L2_PIX_FMT_BGR666, 1},
|
||||
{"BGR24", V4L2_PIX_FMT_BGR24, 1},
|
||||
{"RGB24", V4L2_PIX_FMT_RGB24, 1},
|
||||
{"BGR32", V4L2_PIX_FMT_BGR32, 1},
|
||||
{"ABGR32", V4L2_PIX_FMT_ABGR32, 1},
|
||||
{"XBGR32", V4L2_PIX_FMT_XBGR32, 1},
|
||||
{"RGB32", V4L2_PIX_FMT_RGB32, 1},
|
||||
{"ARGB32", V4L2_PIX_FMT_ARGB32, 1},
|
||||
{"XRGB32", V4L2_PIX_FMT_XRGB32, 1},
|
||||
//{ "HSV24", V4L2_PIX_FMT_HSV24, 1 },
|
||||
//{ "HSV32", V4L2_PIX_FMT_HSV32, 1 },
|
||||
{"Y8", V4L2_PIX_FMT_GREY, 1},
|
||||
{"Y10", V4L2_PIX_FMT_Y10, 1},
|
||||
{"Y12", V4L2_PIX_FMT_Y12, 1},
|
||||
{"Y16", V4L2_PIX_FMT_Y16, 1},
|
||||
{"UYVY", V4L2_PIX_FMT_UYVY, 1},
|
||||
{"VYUY", V4L2_PIX_FMT_VYUY, 1},
|
||||
{"YUYV", V4L2_PIX_FMT_YUYV, 1},
|
||||
{"YVYU", V4L2_PIX_FMT_YVYU, 1},
|
||||
{"NV12", V4L2_PIX_FMT_NV12, 1},
|
||||
{"NV12M", V4L2_PIX_FMT_NV12M, 2},
|
||||
{"NV21", V4L2_PIX_FMT_NV21, 1},
|
||||
{"NV21M", V4L2_PIX_FMT_NV21M, 2},
|
||||
{"NV16", V4L2_PIX_FMT_NV16, 1},
|
||||
{"NV16M", V4L2_PIX_FMT_NV16M, 2},
|
||||
{"NV61", V4L2_PIX_FMT_NV61, 1},
|
||||
{"NV61M", V4L2_PIX_FMT_NV61M, 2},
|
||||
{"NV24", V4L2_PIX_FMT_NV24, 1},
|
||||
{"NV42", V4L2_PIX_FMT_NV42, 1},
|
||||
{"YUV420M", V4L2_PIX_FMT_YUV420M, 3},
|
||||
{"YUV422M", V4L2_PIX_FMT_YUV422M, 3},
|
||||
{"YUV444M", V4L2_PIX_FMT_YUV444M, 3},
|
||||
{"YVU420M", V4L2_PIX_FMT_YVU420M, 3},
|
||||
{"YVU422M", V4L2_PIX_FMT_YVU422M, 3},
|
||||
{"YVU444M", V4L2_PIX_FMT_YVU444M, 3},
|
||||
{"SBGGR8", V4L2_PIX_FMT_SBGGR8, 1},
|
||||
{"SGBRG8", V4L2_PIX_FMT_SGBRG8, 1},
|
||||
{"SGRBG8", V4L2_PIX_FMT_SGRBG8, 1},
|
||||
{"SRGGB8", V4L2_PIX_FMT_SRGGB8, 1},
|
||||
{"SBGGR10_DPCM8", V4L2_PIX_FMT_SBGGR10DPCM8, 1},
|
||||
{"SGBRG10_DPCM8", V4L2_PIX_FMT_SGBRG10DPCM8, 1},
|
||||
{"SGRBG10_DPCM8", V4L2_PIX_FMT_SGRBG10DPCM8, 1},
|
||||
{"SRGGB10_DPCM8", V4L2_PIX_FMT_SRGGB10DPCM8, 1},
|
||||
{"SBGGR10", V4L2_PIX_FMT_SBGGR10, 1},
|
||||
{"SGBRG10", V4L2_PIX_FMT_SGBRG10, 1},
|
||||
{"SGRBG10", V4L2_PIX_FMT_SGRBG10, 1},
|
||||
{"SRGGB10", V4L2_PIX_FMT_SRGGB10, 1},
|
||||
{"SBGGR10P", V4L2_PIX_FMT_SBGGR10P, 1},
|
||||
{"SGBRG10P", V4L2_PIX_FMT_SGBRG10P, 1},
|
||||
{"SGRBG10P", V4L2_PIX_FMT_SGRBG10P, 1},
|
||||
{"SRGGB10P", V4L2_PIX_FMT_SRGGB10P, 1},
|
||||
{"SBGGR12", V4L2_PIX_FMT_SBGGR12, 1},
|
||||
{"SGBRG12", V4L2_PIX_FMT_SGBRG12, 1},
|
||||
{"SGRBG12", V4L2_PIX_FMT_SGRBG12, 1},
|
||||
{"SRGGB12", V4L2_PIX_FMT_SRGGB12, 1},
|
||||
{"DV", V4L2_PIX_FMT_DV, 1},
|
||||
{"MJPEG", V4L2_PIX_FMT_MJPEG, 1},
|
||||
{"MPEG", V4L2_PIX_FMT_MPEG, 1},
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *name;
|
||||
enum v4l2_field field;
|
||||
} fields[] = {
|
||||
{"any", V4L2_FIELD_ANY},
|
||||
{"none", V4L2_FIELD_NONE},
|
||||
{"top", V4L2_FIELD_TOP},
|
||||
{"bottom", V4L2_FIELD_BOTTOM},
|
||||
{"interlaced", V4L2_FIELD_INTERLACED},
|
||||
{"seq-tb", V4L2_FIELD_SEQ_TB},
|
||||
{"seq-bt", V4L2_FIELD_SEQ_BT},
|
||||
{"alternate", V4L2_FIELD_ALTERNATE},
|
||||
{"interlaced-tb", V4L2_FIELD_INTERLACED_TB},
|
||||
{"interlaced-bt", V4L2_FIELD_INTERLACED_BT},
|
||||
};
|
||||
|
||||
GVideoISP1::GVideoISP1()
|
||||
{
|
||||
dev_name = "/dev/video0";
|
||||
}
|
||||
|
||||
GVideoISP1::~GVideoISP1()
|
||||
{
|
||||
}
|
||||
|
||||
void *GVideoISP1::read_frame(int timeout)
|
||||
{
|
||||
if (!wait(timeout))
|
||||
{
|
||||
LOG_TRACE("read frame time out!!!\n");
|
||||
return 0;
|
||||
}
|
||||
struct v4l2_plane planes[VIDEO_MAX_PLANES];
|
||||
v4l2_buffer buf;
|
||||
int ret;
|
||||
memset(&buf, 0, sizeof buf);
|
||||
memset(planes, 0, sizeof planes);
|
||||
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.length = VIDEO_MAX_PLANES;
|
||||
buf.m.planes = planes;
|
||||
|
||||
ret = ioctl(fd, VIDIOC_DQBUF, &buf);
|
||||
if (ret < 0)
|
||||
LOG_TRACE("Unable to dequeue buffer: %s (%d).", strerror(errno), errno);
|
||||
else
|
||||
LOG_TRACE("VIDIOC_DQBUF sucess");
|
||||
|
||||
ret = ioctl(fd, VIDIOC_QBUF, &buf);
|
||||
if (ret < 0)
|
||||
LOG_ERROR("Unable to requeue buffer: %s (%d).\n", strerror(errno), errno);
|
||||
else
|
||||
LOG_TRACE("VIDIOC_QBUF sucess");
|
||||
|
||||
LOG_TRACE("buf.index = %d,buf.addr = %p\n", buf.index, buffers[buf.index].start);
|
||||
return buffers[buf.index].start;
|
||||
}
|
||||
|
||||
void GVideoISP1::start_capturing(void)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
enum v4l2_buf_type type;
|
||||
|
||||
for (i = 0; i < n_buffers; ++i)
|
||||
{
|
||||
struct v4l2_buffer buf;
|
||||
struct v4l2_plane planes[VIDEO_MAX_PLANES];
|
||||
CLEAR(buf);
|
||||
CLEAR(planes);
|
||||
for (int j = 0; j < VIDEO_MAX_PLANES; j++)
|
||||
{
|
||||
planes[j].length = buffers[i].length;
|
||||
planes[j].m.userptr = (unsigned long)buffers[i].start;
|
||||
}
|
||||
buf.index = i;
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.m.planes = planes;
|
||||
buf.length = 1;
|
||||
|
||||
ret = ioctl(fd, VIDIOC_QBUF, &buf);
|
||||
if (ret < 0)
|
||||
LOG_ERROR("Unable to queue buffer: %s (%d).", strerror(errno), errno);
|
||||
else
|
||||
LOG_TRACE("buf.index = %d VIDIOC_QBUF sucess.", i);
|
||||
}
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
ret = ioctl(fd, VIDIOC_STREAMON, &type);
|
||||
if (ret < 0)
|
||||
LOG_ERROR("Unable to %s streaming: %s (%d).", "start", strerror(errno), errno);
|
||||
else
|
||||
LOG_TRACE("VIDIOC_STREAMON sucess.");
|
||||
}
|
||||
|
||||
void GVideoISP1::stop_capturing(void)
|
||||
{
|
||||
enum v4l2_buf_type type;
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &type))
|
||||
LOG_ERROR("streamo off error\n");
|
||||
}
|
||||
|
||||
static void get_ts_flags(uint32_t flags, const char **ts_type, const char **ts_source)
|
||||
{
|
||||
switch (flags & V4L2_BUF_FLAG_TIMESTAMP_MASK)
|
||||
{
|
||||
case V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN:
|
||||
*ts_type = "unk";
|
||||
break;
|
||||
case V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC:
|
||||
*ts_type = "mono";
|
||||
break;
|
||||
case V4L2_BUF_FLAG_TIMESTAMP_COPY:
|
||||
*ts_type = "copy";
|
||||
break;
|
||||
default:
|
||||
*ts_type = "inv";
|
||||
}
|
||||
switch (flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK)
|
||||
{
|
||||
case V4L2_BUF_FLAG_TSTAMP_SRC_EOF:
|
||||
*ts_source = "EoF";
|
||||
break;
|
||||
case V4L2_BUF_FLAG_TSTAMP_SRC_SOE:
|
||||
*ts_source = "SoE";
|
||||
break;
|
||||
default:
|
||||
*ts_source = "inv";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *v4l2_buf_type_name(__u32 type)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(buf_types); ++i)
|
||||
{
|
||||
if (buf_types[i].type == type)
|
||||
return buf_types[i].name;
|
||||
}
|
||||
|
||||
if (type & V4L2_BUF_TYPE_PRIVATE)
|
||||
return "Private";
|
||||
else
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
static const struct v4l2_format_info *v4l2_format_by_fourcc(unsigned int fourcc)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pixel_formats); ++i)
|
||||
{
|
||||
if (pixel_formats[i].fourcc == fourcc)
|
||||
return &pixel_formats[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *v4l2_format_name(unsigned int fourcc)
|
||||
{
|
||||
const struct v4l2_format_info *info;
|
||||
static char name[5];
|
||||
unsigned int i;
|
||||
|
||||
info = v4l2_format_by_fourcc(fourcc);
|
||||
if (info)
|
||||
return info->name;
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
name[i] = fourcc & 0xff;
|
||||
fourcc >>= 8;
|
||||
}
|
||||
|
||||
name[4] = '\0';
|
||||
return name;
|
||||
}
|
||||
|
||||
static void video_enum_frame_intervals(int fd, __u32 pixelformat,
|
||||
unsigned int width, unsigned int height)
|
||||
{
|
||||
struct v4l2_frmivalenum ival;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0;; ++i)
|
||||
{
|
||||
memset(&ival, 0, sizeof ival);
|
||||
ival.index = i;
|
||||
ival.pixel_format = pixelformat;
|
||||
ival.width = width;
|
||||
ival.height = height;
|
||||
ret = ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (i != ival.index)
|
||||
LOG_TRACE("Warning: driver returned wrong ival index "
|
||||
"%u.\n",
|
||||
ival.index);
|
||||
if (pixelformat != ival.pixel_format)
|
||||
LOG_TRACE("Warning: driver returned wrong ival pixel "
|
||||
"format %08x.\n",
|
||||
ival.pixel_format);
|
||||
if (width != ival.width)
|
||||
LOG_TRACE("Warning: driver returned wrong ival width "
|
||||
"%u.\n",
|
||||
ival.width);
|
||||
if (height != ival.height)
|
||||
LOG_TRACE("Warning: driver returned wrong ival height "
|
||||
"%u.\n",
|
||||
ival.height);
|
||||
|
||||
if (i != 0)
|
||||
LOG_TRACE(", ");
|
||||
|
||||
switch (ival.type)
|
||||
{
|
||||
case V4L2_FRMIVAL_TYPE_DISCRETE:
|
||||
LOG_TRACE("%u/%u", ival.discrete.numerator, ival.discrete.denominator);
|
||||
break;
|
||||
|
||||
case V4L2_FRMIVAL_TYPE_CONTINUOUS:
|
||||
LOG_TRACE("%u/%u - %u/%u", ival.stepwise.min.numerator, ival.stepwise.min.denominator, ival.stepwise.max.numerator, ival.stepwise.max.denominator);
|
||||
return;
|
||||
|
||||
case V4L2_FRMIVAL_TYPE_STEPWISE:
|
||||
LOG_TRACE("%u/%u - %u/%u (by %u/%u)", ival.stepwise.min.numerator, ival.stepwise.min.denominator, ival.stepwise.max.numerator, ival.stepwise.max.denominator, ival.stepwise.step.numerator, ival.stepwise.step.denominator);
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void video_enum_frame_sizes(int fd, __u32 pixelformat)
|
||||
{
|
||||
struct v4l2_frmsizeenum frame;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0;; ++i)
|
||||
{
|
||||
memset(&frame, 0, sizeof frame);
|
||||
frame.index = i;
|
||||
frame.pixel_format = pixelformat;
|
||||
ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (i != frame.index)
|
||||
LOG_TRACE("Warning: driver returned wrong frame index "
|
||||
"%u.\n",
|
||||
frame.index);
|
||||
if (pixelformat != frame.pixel_format)
|
||||
LOG_TRACE("Warning: driver returned wrong frame pixel "
|
||||
"format %08x.\n",
|
||||
frame.pixel_format);
|
||||
|
||||
switch (frame.type)
|
||||
{
|
||||
case V4L2_FRMSIZE_TYPE_DISCRETE:
|
||||
LOG_TRACE("\tFrame size: %ux%u (", frame.discrete.width, frame.discrete.height);
|
||||
video_enum_frame_intervals(fd, frame.pixel_format, frame.discrete.width, frame.discrete.height);
|
||||
break;
|
||||
|
||||
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
|
||||
LOG_TRACE("\tFrame size: %ux%u - %ux%u (", frame.stepwise.min_width, frame.stepwise.min_height, frame.stepwise.max_width, frame.stepwise.max_height);
|
||||
video_enum_frame_intervals(fd, frame.pixel_format, frame.stepwise.max_width, frame.stepwise.max_height);
|
||||
break;
|
||||
|
||||
case V4L2_FRMSIZE_TYPE_STEPWISE:
|
||||
LOG_TRACE("\tFrame size: %ux%u - %ux%u (by %ux%u) (\n", frame.stepwise.min_width, frame.stepwise.min_height, frame.stepwise.max_width, frame.stepwise.max_height, frame.stepwise.step_width, frame.stepwise.step_height);
|
||||
video_enum_frame_intervals(fd, frame.pixel_format, frame.stepwise.max_width, frame.stepwise.max_height);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void video_enum_formats(int fd, enum v4l2_buf_type type)
|
||||
{
|
||||
struct v4l2_fmtdesc fmt;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0;; ++i)
|
||||
{
|
||||
memset(&fmt, 0, sizeof fmt);
|
||||
fmt.index = i;
|
||||
fmt.type = type;
|
||||
ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (i != fmt.index)
|
||||
LOG_TRACE("Warning: driver returned wrong format index "
|
||||
"%u.\n",
|
||||
fmt.index);
|
||||
if (type != fmt.type)
|
||||
LOG_TRACE("Warning: driver returned wrong format type "
|
||||
"%u.\n",
|
||||
fmt.type);
|
||||
|
||||
LOG_TRACE("\tFormat %u: %s (%08x)\n", i, v4l2_format_name(fmt.pixelformat), fmt.pixelformat);
|
||||
LOG_TRACE("\tType: %s (%u)\n", v4l2_buf_type_name(fmt.type), fmt.type);
|
||||
LOG_TRACE("\tName: %.32s\n", fmt.description);
|
||||
video_enum_frame_sizes(fd, fmt.pixelformat);
|
||||
}
|
||||
}
|
||||
|
||||
static void video_enum_inputs(int fd)
|
||||
{
|
||||
struct v4l2_input input;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0;; ++i)
|
||||
{
|
||||
memset(&input, 0, sizeof input);
|
||||
input.index = i;
|
||||
ret = ioctl(fd, VIDIOC_ENUMINPUT, &input);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (i != input.index)
|
||||
LOG_TRACE("Warning: driver returned wrong input index "
|
||||
"%u.\n",
|
||||
input.index);
|
||||
|
||||
LOG_TRACE("\tInput %u: %s.\n", i, input.name);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *v4l2_field_name(__u32 field)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fields); ++i)
|
||||
{
|
||||
if (fields[i].field == field)
|
||||
return fields[i].name;
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void rkisp_sd_set_crop(const char *ispsd, int fd, int pad, int *w, int *h)
|
||||
{
|
||||
struct v4l2_subdev_selection sel;
|
||||
int ret;
|
||||
|
||||
memset(&sel, 0, sizeof(sel));
|
||||
sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
sel.pad = pad;
|
||||
sel.r.width = *w;
|
||||
sel.r.height = *h;
|
||||
sel.r.left = 0;
|
||||
sel.r.top = 0;
|
||||
sel.target = V4L2_SEL_TGT_CROP;
|
||||
sel.flags = V4L2_SEL_FLAG_LE;
|
||||
ret = ioctl(fd, VIDIOC_SUBDEV_S_SELECTION, &sel);
|
||||
if (ret)
|
||||
{
|
||||
LOG_ERROR("subdev %s pad %d crop failed, ret = %d\n", ispsd, sel.pad, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_SELECTION sucess.\n");
|
||||
}
|
||||
|
||||
*w = sel.r.width;
|
||||
*h = sel.r.height;
|
||||
}
|
||||
|
||||
static void rkisp_video_set_crop(int fd, int x, int y, int w, int h)
|
||||
{
|
||||
struct v4l2_selection sel;
|
||||
int ret;
|
||||
memset(&sel, 0, sizeof(sel));
|
||||
sel.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
sel.r.width = w;
|
||||
sel.r.height = h;
|
||||
sel.r.left = x;
|
||||
sel.r.top = y;
|
||||
sel.target = V4L2_SEL_TGT_CROP;
|
||||
sel.flags = 0;
|
||||
ret = ioctl(fd, VIDIOC_S_SELECTION, &sel);
|
||||
if (ret)
|
||||
{
|
||||
LOG_ERROR("VIDIOC_S_SELECTION::set output crop(0,0/%dx%d) failed, %s\n", w, h, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("sVIDIOC_S_SELECTION scuess\n");
|
||||
}
|
||||
}
|
||||
|
||||
void GVideoISP1::init_device(void)
|
||||
{
|
||||
struct v4l2_capability cap;
|
||||
struct v4l2_format fmt;
|
||||
|
||||
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
struct v4l2_fmtdesc fmt_1;
|
||||
struct v4l2_frmsizeenum frmsize;
|
||||
struct v4l2_frmivalenum frmival;
|
||||
struct v4l2_subdev_format subdev_fmt;
|
||||
int subdev_fd;
|
||||
|
||||
unsigned int caps;
|
||||
bool has_video;
|
||||
bool has_meta;
|
||||
bool has_capture;
|
||||
bool has_output;
|
||||
bool has_mplane;
|
||||
|
||||
int ret;
|
||||
int i;
|
||||
//---------------------------set /dev/v4l2-subdev*-------------------------------------//
|
||||
//----------------------1.v4l2_subdev2 set format----------------------//
|
||||
subdev_fd = ::open(subdev2_name.c_str(), O_RDWR, 0);
|
||||
if (-1 == subdev_fd)
|
||||
{
|
||||
LOG_ERROR("Cannot open '%s'\n", subdev2_name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("open %s success.fd = %d.\n", subdev2_name.c_str(), subdev_fd);
|
||||
}
|
||||
memset(&subdev_fmt, 0, sizeof subdev_fmt);
|
||||
subdev_fmt.pad = 0;
|
||||
subdev_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_G_FMT, &subdev_fmt);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_ERROR("VIDIOC_SUBDEV_G_FMT failed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT SUCESS\n");
|
||||
}
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT:height = %d;width = %d;code = %d.\n", subdev_fmt.format.height, subdev_fmt.format.width, subdev_fmt.format.code);
|
||||
|
||||
subdev_fmt.format.width = v4l_width;
|
||||
subdev_fmt.format.height = v4l_height;
|
||||
LOG_TRACE("set height = %d\n", subdev_fmt.format.height);
|
||||
LOG_TRACE("set width = %d\n", subdev_fmt.format.width);
|
||||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_ERROR("VIDIOC_SUBDEV_S_FMT failed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_FMT SUCESS\n");
|
||||
}
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_FMT:height = %d;width = %d;code = %d.\n", subdev_fmt.format.height, subdev_fmt.format.width, subdev_fmt.format.code);
|
||||
::close(subdev_fd);
|
||||
//-------------------------------------------------------------//
|
||||
|
||||
//----------------------2.v4l2_subdev0 set format::pad0----------------------//
|
||||
subdev_fd = ::open(subdev0_name.c_str(), O_RDWR, 0);
|
||||
if (-1 == subdev_fd)
|
||||
{
|
||||
LOG_ERROR("Cannot open '%s'\n", subdev0_name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("open %s success.fd = %d.\n", subdev0_name.c_str(), subdev_fd);
|
||||
}
|
||||
memset(&subdev_fmt, 0, sizeof subdev_fmt);
|
||||
subdev_fmt.pad = 0;
|
||||
subdev_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_G_FMT, &subdev_fmt);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_ERROR("VIDIOC_SUBDEV_G_FMT failed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT SUCESS\n");
|
||||
}
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT:pad = %d;height = %d;width = %d;code = %d.\n", subdev_fmt.pad, subdev_fmt.format.height, subdev_fmt.format.width, subdev_fmt.format.code);
|
||||
subdev_fmt.format.width = v4l_width;
|
||||
subdev_fmt.format.height = v4l_height;
|
||||
LOG_TRACE("set height = %d;width = %d\n", subdev_fmt.format.height, subdev_fmt.format.width);
|
||||
|
||||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_ERROR("VIDIOC_SUBDEV_S_FMT failed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_FMT SUCESS\n");
|
||||
}
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_FMT:pad = %d;height = %d;width = %d;code = %d.\n", subdev_fmt.pad, subdev_fmt.format.height, subdev_fmt.format.width, subdev_fmt.format.code);
|
||||
rkisp_sd_set_crop(subdev0_name.c_str(), subdev_fd, 0, &v4l_width, &v4l_height);
|
||||
LOG_TRACE("v4l_set height = %d;width = %d\n", v4l_width, v4l_height);
|
||||
//----------------------3.v4l2_subdev0 set format::pad2----------------------//
|
||||
rkisp_sd_set_crop(subdev0_name.c_str(), subdev_fd, 2, &v4l_width, &v4l_height);
|
||||
LOG_TRACE("v4l_set height = %d;width = %d\n", v4l_width, v4l_height);
|
||||
memset(&subdev_fmt, 0, sizeof subdev_fmt);
|
||||
subdev_fmt.pad = 2;
|
||||
subdev_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_G_FMT, &subdev_fmt);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT failed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT SUCESS\n");
|
||||
}
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT:pad = %d\n", subdev_fmt.pad);
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT:subdev_fmt.format.height = %d\n", subdev_fmt.format.height);
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT:subdev_fmt.format.width = %d\n", subdev_fmt.format.width);
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT:subdev_fmt.format.code = %d\n", subdev_fmt.format.code);
|
||||
subdev_fmt.format.width = v4l_width;
|
||||
subdev_fmt.format.height = v4l_height;
|
||||
LOG_TRACE("set height = %d\n", subdev_fmt.format.height);
|
||||
LOG_TRACE("set width = %d\n", subdev_fmt.format.width);
|
||||
|
||||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_FMT failed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_FMT SUCESS\n");
|
||||
}
|
||||
LOG_TRACE("VIDIOC_SUBDEV_G_FMT:pad = %d\n", subdev_fmt.pad);
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_FMT:subdev_fmt.format.height = %d\n", subdev_fmt.format.height);
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_FMT:subdev_fmt.format.width = %d\n", subdev_fmt.format.width);
|
||||
LOG_TRACE("VIDIOC_SUBDEV_S_FMT:subdev_fmt.format.code = %d\n", subdev_fmt.format.code);
|
||||
//-------------------------------------------------------------//
|
||||
|
||||
//-------4.set video selection(crop) because ispsd size changed------------------//
|
||||
rkisp_video_set_crop(fd, 0, 0, v4l_width, v4l_height);
|
||||
//----------------------1.VIDIOC_QUERYCAP----------------------//
|
||||
memset(&cap, 0, sizeof cap);
|
||||
if (-1 == ioctl(fd, VIDIOC_QUERYCAP, &cap))
|
||||
|
||||
ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_TRACE("VIDIOC_QUERYCAP failed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("cap.capabilities = %x .\n", cap.capabilities);
|
||||
LOG_TRACE("cap.device_caps = %x .\n", cap.device_caps);
|
||||
}
|
||||
caps = cap.capabilities & V4L2_CAP_DEVICE_CAPS
|
||||
? cap.device_caps
|
||||
: cap.capabilities;
|
||||
|
||||
has_video = caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE |
|
||||
V4L2_CAP_VIDEO_CAPTURE |
|
||||
V4L2_CAP_VIDEO_OUTPUT_MPLANE |
|
||||
V4L2_CAP_VIDEO_OUTPUT);
|
||||
// has_meta = caps & (V4L2_CAP_META_CAPTURE |
|
||||
// V4L2_CAP_META_OUTPUT);
|
||||
// has_capture = caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE |
|
||||
// V4L2_CAP_VIDEO_CAPTURE |
|
||||
// V4L2_CAP_META_CAPTURE);
|
||||
has_output = caps & (V4L2_CAP_VIDEO_OUTPUT_MPLANE |
|
||||
V4L2_CAP_VIDEO_OUTPUT |
|
||||
V4L2_CAP_META_OUTPUT);
|
||||
has_mplane = caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE |
|
||||
V4L2_CAP_VIDEO_OUTPUT_MPLANE);
|
||||
|
||||
LOG_TRACE("Device `%s' on `%s' (driver '%s') supports%s%s%s%s %s mplanes.\n", cap.card, cap.bus_info, cap.driver, has_video ? " video," : "", has_meta ? " meta-data," : "", has_capture ? " capture," : "", has_output ? " output," : "", has_mplane ? "with" : "without");
|
||||
|
||||
if (!(cap.capabilities & V4L2_CAP_STREAMING))
|
||||
{
|
||||
LOG_ERROR("%s does not support streaming i/o\n", dev_name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("%s support streaming i/o\n", dev_name.c_str());
|
||||
}
|
||||
//-------------------------------------------------------------//
|
||||
|
||||
//----------------------2.VIDIOC_ENUM_FMT----------------------//
|
||||
LOG_TRACE("- Available formats:\n");
|
||||
LOG_TRACE("------------------------------------------------------\n");
|
||||
LOG_TRACE("fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE = %d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
||||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
||||
|
||||
LOG_TRACE("------------------------------------------------------\n");
|
||||
LOG_TRACE("fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = %d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
||||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
||||
|
||||
LOG_TRACE("------------------------------------------------------\n");
|
||||
LOG_TRACE("fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT = %d\n", V4L2_BUF_TYPE_VIDEO_OUTPUT);
|
||||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT);
|
||||
|
||||
LOG_TRACE("------------------------------------------------------\n");
|
||||
LOG_TRACE("fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = %d\n", V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
||||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
||||
|
||||
LOG_TRACE("------------------------------------------------------\n");
|
||||
LOG_TRACE("fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY = %d\n", V4L2_BUF_TYPE_VIDEO_OVERLAY);
|
||||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_OVERLAY);
|
||||
|
||||
LOG_TRACE("------------------------------------------------------\n");
|
||||
// LOG_TRACE( "fmt.type = V4L2_BUF_TYPE_META_CAPTURE = %d\n", V4L2_BUF_TYPE_META_CAPTURE));
|
||||
// video_enum_formats(fd, V4L2_BUF_TYPE_META_CAPTURE);
|
||||
|
||||
LOG_TRACE("------------------------------------------------------\n");
|
||||
LOG_TRACE("fmt.type = V4L2_BUF_TYPE_META_OUTPUT = %d\n", V4L2_BUF_TYPE_META_OUTPUT);
|
||||
// video_enum_formats(fd, V4L2_BUF_TYPE_META_OUTPUT);
|
||||
LOG_TRACE("------------------------------------------------------\n");
|
||||
//--------------------------------------------------------------//
|
||||
|
||||
//----------------------3.VIDIOC_ENUMINPUT----------------------//
|
||||
LOG_TRACE("- Available inputs:\n");
|
||||
video_enum_inputs(fd);
|
||||
//-------------------------------------------------------------//
|
||||
|
||||
//----------------------4.VIDIOC_S_FMT-------------------------//
|
||||
LOG_TRACE("..........................................................................\n");
|
||||
CLEAR(fmt);
|
||||
// fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
fmt.fmt.pix.width = v4l_width;
|
||||
fmt.fmt.pix.height = v4l_height;
|
||||
LOG_TRACE("v4l2 VIDIOC_S_FMT width:%d, height:%d\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
|
||||
// fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||||
fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_RGB24;
|
||||
fmt.fmt.pix_mp.field = 0;
|
||||
fmt.fmt.pix_mp.num_planes = 1;
|
||||
fmt.fmt.pix_mp.flags = 0;
|
||||
fmt.fmt.pix_mp.plane_fmt[0].bytesperline = 0;
|
||||
fmt.fmt.pix_mp.plane_fmt[0].sizeimage = 0;
|
||||
|
||||
ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_TRACE("Unable to set format: %s (%d).\n", strerror(errno), errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("VIDIOC_S_FMT sucess.\n");
|
||||
}
|
||||
|
||||
LOG_TRACE("Video format set: %s (%08x) %ux%u field %s, %u planes: \n", v4l2_format_name(fmt.fmt.pix_mp.pixelformat), fmt.fmt.pix_mp.pixelformat, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, v4l2_field_name(fmt.fmt.pix_mp.field), fmt.fmt.pix_mp.num_planes);
|
||||
|
||||
for (i = 0; i < fmt.fmt.pix_mp.num_planes; i++)
|
||||
{
|
||||
LOG_TRACE(" * bytesperline %u, buffer size %u\n", fmt.fmt.pix_mp.plane_fmt[i].bytesperline, fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
|
||||
}
|
||||
//-------------------------------------------------------------//
|
||||
|
||||
//----------------------5.VIDIOC_G_FMT-------------------------//
|
||||
memset(&fmt, 0, sizeof fmt);
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_TRACE("Unable to get format: %s (%d).\n", strerror(errno), errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("VIDIOC_G_FMT sucess.");
|
||||
}
|
||||
LOG_TRACE("Video format: %s (%08x) %ux%u field %s, %u planes: \n", v4l2_format_name(fmt.fmt.pix_mp.pixelformat), fmt.fmt.pix_mp.pixelformat, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, v4l2_field_name(fmt.fmt.pix_mp.field), fmt.fmt.pix_mp.num_planes);
|
||||
for (i = 0; i < fmt.fmt.pix_mp.num_planes; i++)
|
||||
LOG_TRACE(" * bytesperline %u, buffer size %u\n", fmt.fmt.pix_mp.plane_fmt[i].bytesperline, fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
|
||||
|
||||
::close(subdev_fd);
|
||||
//-------------------------------------------------------------//
|
||||
|
||||
// 6.VIDIOC_REQBUFS //7.VIDIOC_QUERYBUF mmmap
|
||||
init_mmap();
|
||||
//-------------------------------------------------------------//
|
||||
}
|
||||
|
||||
void GVideoISP1::init_mmap(void)
|
||||
{
|
||||
struct v4l2_requestbuffers req;
|
||||
int ret;
|
||||
unsigned int length;
|
||||
unsigned int offset;
|
||||
|
||||
CLEAR(req);
|
||||
req.count = v4l_buffer_count;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
LOG_INFO("set v4l_buffer_count = %d\n", req.count);
|
||||
LOG_INFO("set v4l_buffer_type = %d\n", req.type);
|
||||
LOG_INFO("set v4l_buffer_memory = %d\n", req.memory);
|
||||
|
||||
ret = ioctl(fd, VIDIOC_REQBUFS, &req);
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_ERROR("Unable to request buffers: %s (%d).\n", strerror(errno), errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO("%s VIDIOC_REQBUFS sucess\n", dev_name.c_str());
|
||||
}
|
||||
LOG_INFO("%u buffers requested.\n", req.count);
|
||||
|
||||
buffers.resize(req.count);
|
||||
if (buffers.empty())
|
||||
LOG_ERROR("Out of memory\n");
|
||||
|
||||
// 7.VIDIOC_QUERYBUF
|
||||
for (n_buffers = 0; n_buffers < req.count; ++n_buffers)
|
||||
{
|
||||
const char *ts_type, *ts_source;
|
||||
struct v4l2_buffer buf;
|
||||
struct v4l2_plane planes[VIDEO_MAX_PLANES];
|
||||
CLEAR(buf);
|
||||
CLEAR(planes);
|
||||
buf.index = n_buffers;
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.length = VIDEO_MAX_PLANES;
|
||||
buf.m.planes = planes;
|
||||
|
||||
ret = ioctl(fd, VIDIOC_QUERYBUF, &buf);
|
||||
if (ret < 0)
|
||||
LOG_ERROR("Unable to query buffer %u: %s (%d).\n", n_buffers, strerror(errno), errno);
|
||||
else
|
||||
LOG_INFO("index %d VIDIOC_QUERYBUF sucess.\n", n_buffers);
|
||||
// mmap
|
||||
unsigned int length;
|
||||
unsigned int offset;
|
||||
length = buf.m.planes[0].length;
|
||||
offset = buf.m.planes[0].m.mem_offset;
|
||||
LOG_INFO("Buffer %u length = %d.\n", n_buffers, length);
|
||||
LOG_INFO("Buffer %u offset = %d.\n", n_buffers, offset);
|
||||
|
||||
buffers[n_buffers].length = length;
|
||||
buffers[n_buffers].start =
|
||||
mmap(NULL /* start anywhere */,
|
||||
length,
|
||||
PROT_READ | PROT_WRITE /* required */,
|
||||
MAP_SHARED /* recommended */,
|
||||
fd, offset);
|
||||
if (buffers[n_buffers].start == MAP_FAILED)
|
||||
LOG_ERROR("Unable to map buffer %u: %s (%d)\n", n_buffers, strerror(errno), errno);
|
||||
else
|
||||
LOG_INFO("Buffer %u mapped at address %p.\n", n_buffers, buffers[n_buffers].start);
|
||||
}
|
||||
}
|
||||
|
||||
void GVideoISP1::uninit_device(void)
|
||||
{
|
||||
if (!buffers.empty())
|
||||
{
|
||||
for (int i = 0; i < buffers.size(); ++i)
|
||||
if (-1 == munmap(buffers[i].start, buffers[i].length))
|
||||
LOG_ERROR("munmap %d error\n", i);
|
||||
|
||||
struct v4l2_requestbuffers req;
|
||||
CLEAR(req);
|
||||
req.count = 0;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
|
||||
if (-1 == ioctl(fd, VIDIOC_REQBUFS, &req))
|
||||
LOG_ERROR("uinit_device VIDIOC_REQBUFS fail\n");
|
||||
|
||||
buffers.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
#include "gvideo.h"
|
||||
|
||||
class GVideoISP1 : public gVideo
|
||||
{
|
||||
public:
|
||||
GVideoISP1();
|
||||
virtual ~GVideoISP1();
|
||||
|
||||
virtual void *read_frame(int timeout);
|
||||
|
||||
protected:
|
||||
virtual void start_capturing(void);
|
||||
virtual void stop_capturing(void);
|
||||
virtual void init_device(void);
|
||||
virtual void init_mmap(void);
|
||||
virtual void uninit_device(void);
|
||||
|
||||
private:
|
||||
const std::string subdev0_name = "/dev/v4l-subdev0";
|
||||
const std::string subdev1_name = "/dev/v4l-subdev1";
|
||||
const std::string subdev2_name = "/dev/v4l-subdev2";
|
||||
const std::string subdev3_name = "/dev/v4l-subdev3";
|
||||
};
|
|
@ -0,0 +1,316 @@
|
|||
#include "hgutils.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <iostream>
|
||||
#include "CImageMerge.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
cv::Mat extractRepresentRow(const cv::Mat &src)
|
||||
{
|
||||
printf("extractRepresentRow2 enter \n");
|
||||
Mat src_temp(src.rows, src.step, CV_8UC1, src.data);
|
||||
Mat dst(1, src.cols, CV_8UC(src.channels()));
|
||||
Mat dst_temp(1, src.step, CV_8UC1, dst.data);
|
||||
|
||||
for (int i = 0, length = src.step; i < length; i++)
|
||||
{
|
||||
Mat col = src_temp(Rect(i, 0, 1, src_temp.rows));
|
||||
float value = 0;
|
||||
for (int j = 0, rows = col.rows; j < rows; j++)
|
||||
{
|
||||
value += (float)col.at<unsigned char>(Point(0, j)) / rows;
|
||||
}
|
||||
dst_temp.data[i] = (int)value;
|
||||
}
|
||||
printf("extractRepresentRow2 exit \n");
|
||||
return dst;
|
||||
}
|
||||
|
||||
cv::Mat flipRightHalf(Mat &src, int papertype)
|
||||
{
|
||||
Mat left = src(cv::Rect(0, 0, src.cols / 2, src.rows));
|
||||
Mat right = src(cv::Rect(src.cols / 2, 0, src.cols / 2, src.rows));
|
||||
Mat rightFlip;
|
||||
if (papertype == (int)(PaperSize::G400_A4R))
|
||||
{
|
||||
flip(right, rightFlip, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
flip(right, rightFlip, 1);
|
||||
}
|
||||
|
||||
Mat dst;
|
||||
hconcat(left, rightFlip, dst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
float curve_coffes[2][3][3] = {
|
||||
{{-6e-5, 0.9928, 0.289},
|
||||
{4e-5, 1.0045, -0.0338},
|
||||
{3e-5, 1.0028, -0.2547}},
|
||||
{{0.00025215105482649316, 0.9162675232424231, 2.2064225897716527},
|
||||
{-6.242394612635725e-05, 1.0212590446315797, -0.7470581333124157},
|
||||
{-0.0002324551311266845, 1.072239346671703, -1.7099159032971474}}};
|
||||
|
||||
cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, bool colormode, CISVendor vendor)
|
||||
{
|
||||
printf("create_lut enter \n");
|
||||
int channel = 4896 / 12; // 1632*3
|
||||
|
||||
const int rows = black.cols / channel; // 408
|
||||
const int cols = 256;
|
||||
printf("LUT White width: %d height :%d channels:%d \n", white.cols, white.rows, white.channels());
|
||||
printf("LUT black width: %d height :%d channels:%d \n", black.cols, black.rows, black.channels());
|
||||
Mat lut(rows, cols, CV_8UC(channel));
|
||||
float *cisCoffoes;
|
||||
float *coffoes;
|
||||
if (vendor == CISVendor::DUNNAN_CIS_V0)
|
||||
cisCoffoes = &curve_coffes[0][0][0];
|
||||
else if (vendor == CISVendor::HUALIN_CIS_V0)
|
||||
cisCoffoes = &curve_coffes[1][0][0];
|
||||
else
|
||||
{
|
||||
cisCoffoes = &curve_coffes[1][0][0];
|
||||
printf("warnning!!! unknown cis type,use hualin CIS cisCoffoes params \n");
|
||||
}
|
||||
|
||||
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;
|
||||
printf("ptr_black[%d] >= ptr_white[%d]", k, k);
|
||||
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
|
||||
{
|
||||
if (white.channels() == 3)
|
||||
{
|
||||
float val = 255.0 * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]) * 1.2;
|
||||
// float val = 255.0 * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]);
|
||||
// coffoes = cisCoffoes + 3 * (k % 3);
|
||||
// val = coffoes[0] * val * val + coffoes[1] * val + coffoes[2];
|
||||
if (val > 255)
|
||||
val = 255;
|
||||
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
ptr_buffer[j * channel + k] = (unsigned char)val;
|
||||
}
|
||||
else
|
||||
{
|
||||
// float val = 255 * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]);
|
||||
float val = 255 * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]) * 1.2;
|
||||
if (val > 255)
|
||||
val = 255;
|
||||
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
ptr_buffer[j * channel + k] = (unsigned char)val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("create_lut exit \n");
|
||||
return lut;
|
||||
}
|
||||
|
||||
void initLut()
|
||||
{
|
||||
if (access(LUT_GRAY_LUT_PATH, F_OK) != -1)
|
||||
lutGrayMat_old = cv::imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE); // 灰色校正值
|
||||
if (access(LUT_COLOR_LUT_PATH, F_OK) != -1)
|
||||
lutColorMat_old = cv::imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE); // 彩色校正值
|
||||
}
|
||||
|
||||
void correctColor(cv::Mat src, bool enhance)
|
||||
{
|
||||
Mat tSrc;
|
||||
Mat lutMat;
|
||||
int patch = 0;
|
||||
int SIZE = src.cols / 12;
|
||||
// printf("lutMat.empty() src.width::%d SIZE: %d \n", src.cols, SIZE);
|
||||
|
||||
if (src.type() == CV_8UC3)
|
||||
{
|
||||
patch = (src.cols * 3) / SIZE;
|
||||
if (lutColorMat_old.empty())
|
||||
{
|
||||
if (access(LUT_COLOR_LUT_PATH, F_OK) != -1)
|
||||
{
|
||||
lutColorMat_old = imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("error error error %s NOT FOUND \n", LUT_COLOR_LUT_PATH);
|
||||
return;
|
||||
}
|
||||
}
|
||||
lutMat = lutColorMat_old;
|
||||
}
|
||||
else
|
||||
{
|
||||
patch = (src.cols) / SIZE;
|
||||
if (lutGrayMat_old.empty())
|
||||
{
|
||||
if (access(LUT_GRAY_LUT_PATH, F_OK) != -1)
|
||||
{
|
||||
lutGrayMat_old = imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("error error error %s NOT FOUND", LUT_GRAY_LUT_PATH);
|
||||
return;
|
||||
}
|
||||
}
|
||||
lutMat = lutGrayMat_old;
|
||||
}
|
||||
if (lutMat.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
lutMat = cv::Mat(patch, 256, CV_8UC(SIZE), lutMat.data);
|
||||
tSrc = cv::Mat(src.rows, patch, CV_8UC(SIZE), src.data);
|
||||
for (int i = 0; i < patch; i++)
|
||||
{
|
||||
LUT(tSrc(cv::Rect(i, 0, 1, src.rows)), lutMat(cv::Rect(0, i, 256, 1)), tSrc(cv::Rect(i, 0, 1, src.rows)));
|
||||
}
|
||||
}
|
||||
|
||||
void creatLUTData(int mode, CISVendor vendor)
|
||||
{
|
||||
printf("eneter creatLUTData \n");
|
||||
auto colormode = mode == IMAGE_COLOR ? IMREAD_COLOR : IMREAD_GRAYSCALE;
|
||||
std::string blackPath = mode == IMAGE_COLOR ? LUT_COLOR_BLACK_PATH : LUT_GRAY_BLACK_PATH;
|
||||
std::string whitePath = mode == IMAGE_COLOR ? LUT_COLOR_WHITE_PATH : LUT_GRAY_WHITE_PATH;
|
||||
std::string lutsavePath = mode == IMAGE_COLOR ? LUT_COLOR_LUT_PATH : LUT_GRAY_LUT_PATH;
|
||||
cv::Mat lut;
|
||||
cv::Mat twMat = cv::imread(whitePath, colormode);
|
||||
cv::Mat tbMat = cv::imread(blackPath, colormode);
|
||||
cv::Mat wMat, bMat;
|
||||
if (mode == IMAGE_COLOR)
|
||||
{
|
||||
wMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, twMat.data);
|
||||
bMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, tbMat.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
wMat = twMat;
|
||||
bMat = tbMat;
|
||||
}
|
||||
|
||||
lut = create_lut(extractRepresentRow(bMat), extractRepresentRow(wMat), mode, vendor); // add by liuyong: 刘丁维提供 2019/4/12
|
||||
Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1);
|
||||
memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256);
|
||||
cv::imwrite(lutsavePath, dst);
|
||||
printf("exit creatLUTData \n");
|
||||
}
|
||||
static int num = 0;
|
||||
cv::Mat GetMergeMat(void *data, int width, int height, int type)
|
||||
{
|
||||
if (!data)
|
||||
return cv::Mat();
|
||||
|
||||
cv::Mat mat;
|
||||
cv::Mat saveMat;
|
||||
std::vector<cv::Mat> ch_mats(3);
|
||||
int dstwidth, dstheight;
|
||||
dstwidth = width * 3;
|
||||
dstheight = height / 3 - 1;
|
||||
|
||||
if (type == CV_8UC3)
|
||||
{
|
||||
mat = cv::Mat(height / 3 - 1, width * 9, CV_8UC1, data);
|
||||
saveMat = cv::Mat(dstheight, dstwidth, CV_8UC3);
|
||||
}
|
||||
else
|
||||
{ // gray
|
||||
saveMat = cv::Mat(height, width * 3, CV_8UC1, data);
|
||||
}
|
||||
static int savenum;
|
||||
if (type == CV_8UC3)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{ // B G R
|
||||
cv::Mat mattemp = mat(cv::Rect(dstwidth * i, 0, dstwidth, dstheight));
|
||||
// ch_mats.push_back(mattemp);
|
||||
ch_mats[i] = mattemp;
|
||||
}
|
||||
swap(ch_mats[1], ch_mats[2]);
|
||||
cv::merge(ch_mats, saveMat);
|
||||
}
|
||||
return saveMat.clone();
|
||||
}
|
||||
|
||||
// 3399 旧版本 华凌cis拼接算法
|
||||
cv::Mat GetMergeMat(cv::Mat &mat, int width, int height, int type)
|
||||
{
|
||||
if (mat.empty())
|
||||
return cv::Mat();
|
||||
cv::Mat saveMat;
|
||||
std::vector<cv::Mat> ch_mats(3);
|
||||
int dstwidth, dstheight;
|
||||
dstwidth = width * 3;
|
||||
dstheight = height / 3 - 1;
|
||||
|
||||
if (type == CV_8UC3)
|
||||
{
|
||||
saveMat = cv::Mat(dstheight, dstwidth, CV_8UC3);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{ // B G R
|
||||
cv::Mat mattemp = mat(cv::Rect(dstwidth * i, 0, dstwidth, dstheight));
|
||||
// ch_mats.push_back(mattemp);
|
||||
ch_mats[i] = mattemp;
|
||||
}
|
||||
swap(ch_mats[1], ch_mats[2]);
|
||||
cv::merge(ch_mats, saveMat);
|
||||
return saveMat;
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
|
||||
// 3399 敦南cis 300 600 拼接算法
|
||||
cv::Mat GetMergeMat(int dstwidth, int dstheight, int type, cv::Mat &mat, unsigned int fpgaversion)
|
||||
{
|
||||
return CImageMerge().MergeImage(type == CV_8UC3, mat, dstwidth, dstheight, fpgaversion);
|
||||
}
|
||||
|
||||
void savescannerinfo(ScannerNativeParam params)
|
||||
{
|
||||
Get_static_jsonconfig().savescannerinfo(params);
|
||||
}
|
||||
|
||||
ScannerNativeParam getscannerinfo()
|
||||
{
|
||||
return Get_static_jsonconfig().getscannerinfo();
|
||||
}
|
||||
|
||||
void savecisparams(HGCorrectConfigs cfgs)
|
||||
{
|
||||
Get_static_jsonconfig().savecisconfig(cfgs);
|
||||
}
|
||||
|
||||
HGCorrectConfigs getcisparams()
|
||||
{
|
||||
return Get_static_jsonconfig().getcorrectconfigs();
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "jsonconfig.h"
|
||||
#include "commondef.h"
|
||||
|
||||
static cv::Mat lutGrayMat_old; // 灰色校正值
|
||||
static cv::Mat lutColorMat_old; // 彩色校正值
|
||||
|
||||
cv::Mat extractRepresentRow(const cv::Mat &src);
|
||||
|
||||
cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, bool colormode, CISVendor vendor);
|
||||
|
||||
cv::Mat flipRightHalf(cv::Mat &src, int papertype);
|
||||
|
||||
void initLut();
|
||||
|
||||
cv::Mat GetMergeMat(void *data, int width, int height, int type);
|
||||
|
||||
cv::Mat GetMergeMat(cv::Mat &mat, int width, int height, int type);
|
||||
|
||||
cv::Mat GetMergeMat(int dstwidth, int dstheight, int type, cv::Mat &mat, unsigned int fpgaversion = 0x00090001);
|
||||
|
||||
void correctColor(cv::Mat src, bool enhance);
|
||||
|
||||
void creatLUTData(int mode, CISVendor vendor);
|
||||
|
||||
void savescannerinfo(ScannerNativeParam params);
|
||||
|
||||
ScannerNativeParam getscannerinfo();
|
||||
|
||||
void savecisparams(HGCorrectConfigs cfgs);
|
||||
|
||||
HGCorrectConfigs getcisparams();
|
|
@ -0,0 +1,442 @@
|
|||
#include "jsonconfig.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#define SP_COLOR_DEFAULT 0x438
|
||||
#define SP_GRAY_DEFAULT 0xca8
|
||||
|
||||
jsonconfig m_static_jsonconfig;
|
||||
|
||||
jsonconfig::jsonconfig()
|
||||
{
|
||||
getscannerinfo();
|
||||
}
|
||||
|
||||
jsonconfig::~jsonconfig()
|
||||
{
|
||||
}
|
||||
|
||||
void jsonconfig::savecisconfig(HGCorrectConfigs configs)
|
||||
{
|
||||
if (access(JSON_CORRECTDIR_PATH, 0) == -1)
|
||||
{
|
||||
auto ret = mkdir(JSON_CORRECTDIR_PATH, 0777);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("make dir failed .path=%s \n", JSON_CORRECTDIR_PATH);
|
||||
}
|
||||
}
|
||||
json m_json;
|
||||
m_json[STRCON(STR_COLOR, STR_EXPF)] = configs.color.expF;
|
||||
m_json[STRCON(STR_COLOR, STR_EXPB)] = configs.color.expB;
|
||||
m_json[STRCON(STR_COLOR, STR_GAINF)] = configs.color.gainF;
|
||||
m_json[STRCON(STR_COLOR, STR_GAINB)] = configs.color.gainB;
|
||||
m_json[STRCON(STR_COLOR, STR_OFFSETF)] = configs.color.offsetsF;
|
||||
m_json[STRCON(STR_COLOR, STR_OFFSETB)] = configs.color.offsetsB;
|
||||
if (configs.color.sp <= 0)
|
||||
{
|
||||
configs.color.sp = SP_COLOR_DEFAULT;
|
||||
}
|
||||
m_json[STRCON(STR_COLOR, STR_SP)] = configs.color.sp;
|
||||
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_EXPF)] = configs.colorCorrect.expF;
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_EXPB)] = configs.colorCorrect.expB;
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_GAINF)] = configs.colorCorrect.gainF;
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_GAINB)] = configs.colorCorrect.gainB;
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_OFFSETF)] = configs.colorCorrect.offsetsF;
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_OFFSETB)] = configs.colorCorrect.offsetsB;
|
||||
if (configs.colorCorrect.sp <= 0)
|
||||
{
|
||||
configs.colorCorrect.sp = SP_COLOR_DEFAULT;
|
||||
}
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_SP)] = configs.colorCorrect.sp;
|
||||
|
||||
m_json[STRCON(STR_GRAY, STR_EXPF)] = configs.gray.expF;
|
||||
m_json[STRCON(STR_GRAY, STR_EXPB)] = configs.gray.expB;
|
||||
m_json[STRCON(STR_GRAY, STR_GAINF)] = configs.gray.gainF;
|
||||
m_json[STRCON(STR_GRAY, STR_GAINB)] = configs.gray.gainB;
|
||||
m_json[STRCON(STR_GRAY, STR_OFFSETF)] = configs.gray.offsetsF;
|
||||
m_json[STRCON(STR_GRAY, STR_OFFSETB)] = configs.gray.offsetsB;
|
||||
if (configs.gray.sp <= 0)
|
||||
{
|
||||
configs.gray.sp = SP_GRAY_DEFAULT;
|
||||
}
|
||||
m_json[STRCON(STR_GRAY, STR_SP)] = configs.gray.sp;
|
||||
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_EXPF)] = configs.grayCorrect.expF;
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_EXPB)] = configs.grayCorrect.expB;
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_GAINF)] = configs.grayCorrect.gainF;
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_GAINB)] = configs.grayCorrect.gainB;
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_OFFSETF)] = configs.grayCorrect.offsetsF;
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_OFFSETB)] = configs.grayCorrect.offsetsB;
|
||||
if (configs.grayCorrect.sp <= 0)
|
||||
{
|
||||
configs.grayCorrect.sp = SP_GRAY_DEFAULT;
|
||||
}
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_SP)] = configs.grayCorrect.sp;
|
||||
|
||||
std::cout << m_json << std::endl;
|
||||
|
||||
std::ofstream o(JSON_CORRECTFILE_PATH);
|
||||
o << std::setw(4) << m_json << std::endl;
|
||||
o.close();
|
||||
}
|
||||
|
||||
HGCorrectConfigs jsonconfig::getcorrectconfigs()
|
||||
{
|
||||
HGCorrectConfigs cfs;
|
||||
if (access(JSON_CORRECTDIR_PATH, 0) == -1)
|
||||
{
|
||||
auto ret = mkdir(JSON_CORRECTDIR_PATH, 0777);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("make dir failed .path=%s \n", JSON_CORRECTDIR_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
if (access(JSON_CORRECTFILE_PATH, F_OK) != 0)
|
||||
{
|
||||
cfs = getdefaultconfigs();
|
||||
savecisconfig(cfs);
|
||||
return cfs;
|
||||
}
|
||||
|
||||
std::ifstream i(JSON_CORRECTFILE_PATH);
|
||||
auto pos = i.tellg();
|
||||
i.seekg(0, std::ios::end);
|
||||
// printf("file length =%d ", i.tellg());
|
||||
if (i.tellg() <= 2)
|
||||
{
|
||||
cfs = getdefaultconfigs();
|
||||
savecisconfig(cfs);
|
||||
return cfs;
|
||||
}
|
||||
i.seekg(pos);
|
||||
json m_json;
|
||||
i >> m_json;
|
||||
i.close();
|
||||
cfs.colorCorrect.sp = cfs.color.sp = SP_COLOR_DEFAULT;
|
||||
cfs.grayCorrect.sp = cfs.gray.sp = SP_GRAY_DEFAULT;
|
||||
std::cout << "GET GET GET GET GET GET" << m_json << std::endl;
|
||||
m_json[STRCON(STR_COLOR, STR_EXPF)].get_to(cfs.color.expF);
|
||||
m_json[STRCON(STR_COLOR, STR_EXPB)].get_to(cfs.color.expB);
|
||||
m_json[STRCON(STR_COLOR, STR_GAINF)].get_to(cfs.color.gainF);
|
||||
m_json[STRCON(STR_COLOR, STR_GAINB)].get_to(cfs.color.gainB);
|
||||
m_json[STRCON(STR_COLOR, STR_OFFSETF)].get_to(cfs.color.offsetsF);
|
||||
m_json[STRCON(STR_COLOR, STR_OFFSETB)].get_to(cfs.color.offsetsB);
|
||||
m_json[STRCON(STR_COLOR, STR_SP)].get_to(cfs.color.sp);
|
||||
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_EXPF)].get_to(cfs.colorCorrect.expF);
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_EXPB)].get_to(cfs.colorCorrect.expB);
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_GAINF)].get_to(cfs.colorCorrect.gainF);
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_GAINB)].get_to(cfs.colorCorrect.gainB);
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_OFFSETF)].get_to(cfs.colorCorrect.offsetsF);
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_OFFSETB)].get_to(cfs.colorCorrect.offsetsB);
|
||||
m_json[STRCON(STR_CORRECTCOLOR, STR_SP)].get_to(cfs.colorCorrect.sp);
|
||||
|
||||
m_json[STRCON(STR_GRAY, STR_EXPF)].get_to(cfs.gray.expF);
|
||||
m_json[STRCON(STR_GRAY, STR_EXPB)].get_to(cfs.gray.expB);
|
||||
m_json[STRCON(STR_GRAY, STR_GAINF)].get_to(cfs.gray.gainF);
|
||||
m_json[STRCON(STR_GRAY, STR_GAINB)].get_to(cfs.gray.gainB);
|
||||
m_json[STRCON(STR_GRAY, STR_OFFSETF)].get_to(cfs.gray.offsetsF);
|
||||
m_json[STRCON(STR_GRAY, STR_OFFSETB)].get_to(cfs.gray.offsetsB);
|
||||
m_json[STRCON(STR_GRAY, STR_SP)].get_to(cfs.gray.sp);
|
||||
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_EXPF)].get_to(cfs.grayCorrect.expF);
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_EXPB)].get_to(cfs.grayCorrect.expB);
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_GAINF)].get_to(cfs.grayCorrect.gainF);
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_GAINB)].get_to(cfs.grayCorrect.gainB);
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_OFFSETF)].get_to(cfs.grayCorrect.offsetsF);
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_OFFSETB)].get_to(cfs.grayCorrect.offsetsB);
|
||||
m_json[STRCON(STR_CORRECTGRAY, STR_SP)].get_to(cfs.grayCorrect.sp);
|
||||
return cfs;
|
||||
}
|
||||
|
||||
HGCorrectConfigs jsonconfig::getdefaultconfigs()
|
||||
{
|
||||
HGCorrectConfigs cfs;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
|
||||
int expclorF, expgrayF, expclorB, expgrayB;
|
||||
switch (i)
|
||||
{
|
||||
case 0: // B
|
||||
expclorF = 1300; // 789
|
||||
expclorB = 1350;
|
||||
expgrayF = 420;
|
||||
expgrayB = 420;
|
||||
break;
|
||||
case 1: // G
|
||||
expclorF = 1350;
|
||||
expclorB = 1280;
|
||||
expgrayF = 420;
|
||||
expgrayB = 420;
|
||||
break;
|
||||
case 2: // R
|
||||
expclorF = 789;
|
||||
expclorB = 824;
|
||||
expgrayF = 420;
|
||||
expgrayB = 420;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cfs.colorCorrect.expB[i] = expclorF;
|
||||
cfs.colorCorrect.expF[i] = expclorB;
|
||||
cfs.grayCorrect.expB[i] = expgrayF;
|
||||
cfs.grayCorrect.expF[i] = expgrayB;
|
||||
cfs.gray.expB[i] = expgrayB;
|
||||
cfs.gray.expF[i] = expgrayF;
|
||||
cfs.color.expF[i] = expclorF;
|
||||
cfs.color.expB[i] = expclorB;
|
||||
}
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
cfs.colorCorrect.gainB[i] = cfs.colorCorrect.gainF[i] = 120;
|
||||
cfs.grayCorrect.gainB[i] = cfs.grayCorrect.gainF[i] = 120;
|
||||
cfs.gray.gainB[i] = cfs.gray.gainF[i] = 120;
|
||||
cfs.color.gainB[i] = cfs.color.gainF[i] = 120;
|
||||
cfs.colorCorrect.offsetsB[i] = cfs.colorCorrect.offsetsF[i] = 125;
|
||||
cfs.grayCorrect.offsetsB[i] = cfs.grayCorrect.offsetsF[i] = 125;
|
||||
cfs.gray.offsetsB[i] = cfs.gray.offsetsF[i] = 125;
|
||||
cfs.color.offsetsB[i] = cfs.color.offsetsF[i] = 125;
|
||||
}
|
||||
|
||||
cfs.colorCorrect.sp = cfs.color.sp = SP_COLOR_DEFAULT;
|
||||
cfs.grayCorrect.sp = cfs.gray.sp = SP_GRAY_DEFAULT;
|
||||
return cfs;
|
||||
}
|
||||
|
||||
void jsonconfig::savescannerinfo(ScannerNativeParam param)
|
||||
{
|
||||
m_mem_param = param;
|
||||
json m_json;
|
||||
m_json[S_INFO_DOUNUM] = (param.DoubleFeedTimes);
|
||||
m_json[S_INFO_FEEDERROR] = (param.FeedErrorTimes);
|
||||
m_json[S_INFO_HRATIO] = (param.H_ratio);
|
||||
m_json[S_INFO_JAMNUM] = (param.JamTimes);
|
||||
m_json[S_INFO_ROLLERNUM] = (param.RollerNum);
|
||||
m_json[S_INFO_SCANSESSIONCOUNT] = (param.ScanSessionsCount);
|
||||
m_json[S_INFO_SERIALNUM] = (param.SerialNum);
|
||||
m_json[S_INFO_TOKEN] = (param.Token);
|
||||
m_json[S_INFO_TOTALSCANNED] = (param.TotalScanned);
|
||||
m_json[S_INFO_VRATIO] = (param.V_ratio);
|
||||
m_json[S_COLOR_SP] = (param.color_sp);
|
||||
m_json[S_GRAY_SP] = (param.gray_sp);
|
||||
m_json[S_INFO_SLEEPTIME] = (param.sleeptime);
|
||||
m_json[S_INFO_CLR_MAXBRT] = (param.clr_maxbright);
|
||||
m_json[S_INFO_GRAY_MAXBRT] = (param.gray_maxbright);
|
||||
m_json[S_INFO_SPEEDMODE] = (param.speedmode);
|
||||
m_json[S_INFO_VID] = (param.Vid);
|
||||
m_json[S_INFO_PID] = (param.Pid);
|
||||
m_json[S_INFO_CHUZHI_MOTOR_SPEED_200] = (param.chu_motor_speed_200);
|
||||
m_json[S_INFO_CHUZHI_MOTOR_SPEED_300] = (param.chu_motor_speed_300);
|
||||
m_json[S_INFO_CHUZHI_MOTOR_SPEED_600] = (param.chu_motor_speed_600);
|
||||
std::ofstream o(JSON_SCANNER_INFO_FILE);
|
||||
o << std::setw(4) << m_json << std::endl;
|
||||
o.close();
|
||||
printf("\n %s speedmode value = %d", JSON_SCANNER_INFO_FILE, param.speedmode);
|
||||
}
|
||||
|
||||
ScannerNativeParam jsonconfig::getscannerinfo()
|
||||
{
|
||||
std::lock_guard<std::mutex> lc(mtx);
|
||||
|
||||
ScannerNativeParam snp;
|
||||
|
||||
if (access(JSON_SCANNER_INFO_DIR, 0) == -1)
|
||||
{
|
||||
auto ret = mkdir(JSON_SCANNER_INFO_DIR, 0777);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("make dir failed .path=%s \n", JSON_SCANNER_INFO_DIR);
|
||||
}
|
||||
}
|
||||
if (access(JSON_SCANNER_INFO_FILE, 0) == -1)
|
||||
{
|
||||
printf("\nerror !!! file no exist");
|
||||
snp = getdefaultscannerinfo();
|
||||
savescannerinfo(snp);
|
||||
return snp;
|
||||
}
|
||||
std::ifstream i(JSON_SCANNER_INFO_FILE);
|
||||
|
||||
auto pos = i.tellg();
|
||||
|
||||
i.seekg(0, std::ios::end);
|
||||
|
||||
// printf("file length =%d ", i.tellg());
|
||||
if (i.tellg() <= 2)
|
||||
{
|
||||
printf("\nerror !!! file data error");
|
||||
snp = getdefaultscannerinfo();
|
||||
savescannerinfo(snp);
|
||||
return snp;
|
||||
}
|
||||
i.seekg(pos);
|
||||
json m_json;
|
||||
i >> m_json;
|
||||
|
||||
if (!m_json[S_INFO_DOUNUM].is_null())
|
||||
m_json[S_INFO_DOUNUM].get_to(snp.DoubleFeedTimes);
|
||||
else
|
||||
snp.DoubleFeedTimes = 0;
|
||||
|
||||
if (!m_json[S_INFO_FEEDERROR].is_null())
|
||||
m_json[S_INFO_FEEDERROR].get_to(snp.FeedErrorTimes);
|
||||
else
|
||||
snp.FeedErrorTimes = 0;
|
||||
|
||||
if (!m_json[S_INFO_HRATIO].is_null())
|
||||
m_json[S_INFO_HRATIO].get_to(snp.H_ratio);
|
||||
else
|
||||
snp.H_ratio = 1065353216;
|
||||
|
||||
if (!m_json[S_INFO_JAMNUM].is_null())
|
||||
m_json[S_INFO_JAMNUM].get_to(snp.JamTimes);
|
||||
else
|
||||
snp.JamTimes = 0;
|
||||
|
||||
if (!m_json[S_INFO_ROLLERNUM].is_null())
|
||||
m_json[S_INFO_ROLLERNUM].get_to(snp.RollerNum);
|
||||
else
|
||||
snp.RollerNum = 0;
|
||||
if (!m_json[S_INFO_SCANSESSIONCOUNT].is_null())
|
||||
m_json[S_INFO_SCANSESSIONCOUNT].get_to(snp.ScanSessionsCount);
|
||||
else
|
||||
snp.ScanSessionsCount = 0;
|
||||
|
||||
if (!m_json[S_INFO_SERIALNUM].is_null())
|
||||
m_json[S_INFO_SERIALNUM].get_to(snp.SerialNum);
|
||||
else
|
||||
snp.SerialNum = SERIALNUM;
|
||||
|
||||
if (!m_json[S_INFO_TOKEN].is_null())
|
||||
m_json[S_INFO_TOKEN].get_to(snp.Token);
|
||||
else
|
||||
snp.Token = "abcdefghijklmnopqrstuvwxyz012345";
|
||||
|
||||
if (!m_json[S_INFO_TOTALSCANNED].is_null())
|
||||
m_json[S_INFO_TOTALSCANNED].get_to(snp.TotalScanned);
|
||||
else
|
||||
snp.TotalScanned = 0;
|
||||
|
||||
if (!m_json[S_INFO_VRATIO].is_null())
|
||||
m_json[S_INFO_VRATIO].get_to(snp.V_ratio);
|
||||
else
|
||||
snp.V_ratio = 1065353216;
|
||||
|
||||
if (!m_json[S_COLOR_SP].is_null())
|
||||
m_json[S_COLOR_SP].get_to(snp.color_sp);
|
||||
else
|
||||
#ifdef G200
|
||||
snp.color_sp = 0x27C;
|
||||
#else
|
||||
snp.color_sp = 0x2B6;
|
||||
#endif
|
||||
|
||||
if (!m_json[S_GRAY_SP].is_null())
|
||||
m_json[S_GRAY_SP].get_to(snp.gray_sp);
|
||||
else
|
||||
#ifdef G200
|
||||
snp.gray_sp = 0x775;
|
||||
#else
|
||||
snp.gray_sp = 0x822;
|
||||
#endif
|
||||
|
||||
if (!m_json[S_INFO_SLEEPTIME].is_null())
|
||||
m_json[S_INFO_SLEEPTIME].get_to(snp.sleeptime);
|
||||
else
|
||||
snp.sleeptime = 10800;
|
||||
|
||||
if (!m_json[S_INFO_CLR_MAXBRT].is_null())
|
||||
m_json[S_INFO_CLR_MAXBRT].get_to(snp.clr_maxbright);
|
||||
else
|
||||
snp.clr_maxbright = 200;
|
||||
|
||||
if (!m_json[S_INFO_GRAY_MAXBRT].is_null())
|
||||
m_json[S_INFO_GRAY_MAXBRT].get_to(snp.gray_maxbright);
|
||||
else
|
||||
snp.gray_maxbright = 200;
|
||||
|
||||
if (!m_json[S_INFO_SPEEDMODE].is_null())
|
||||
m_json[S_INFO_SPEEDMODE].get_to(snp.speedmode), printf("\n %s Get speedmode value = %d", JSON_SCANNER_INFO_FILE, snp.speedmode);
|
||||
else
|
||||
snp.speedmode = 0, printf("\n %s Get speedmode failed ", JSON_SCANNER_INFO_FILE);
|
||||
|
||||
if (!m_json[S_INFO_PID].is_null())
|
||||
m_json[S_INFO_PID].get_to(snp.Pid);
|
||||
else
|
||||
{
|
||||
#ifdef G100
|
||||
snp.Pid = 0x139;
|
||||
#else
|
||||
snp.Pid = 0x239;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!m_json[S_INFO_VID].is_null())
|
||||
m_json[S_INFO_VID].get_to(snp.Vid);
|
||||
else
|
||||
snp.Vid = 0x3072;
|
||||
|
||||
if (!m_json[S_INFO_CHUZHI_MOTOR_SPEED_200].is_null())
|
||||
m_json[S_INFO_CHUZHI_MOTOR_SPEED_200].get_to(snp.chu_motor_speed_200);
|
||||
else
|
||||
snp.chu_motor_speed_200 = 300;
|
||||
|
||||
if (!m_json[S_INFO_CHUZHI_MOTOR_SPEED_300].is_null())
|
||||
m_json[S_INFO_CHUZHI_MOTOR_SPEED_300].get_to(snp.chu_motor_speed_300);
|
||||
else
|
||||
snp.chu_motor_speed_300 = 200;
|
||||
|
||||
if (!m_json[S_INFO_CHUZHI_MOTOR_SPEED_600].is_null())
|
||||
m_json[S_INFO_CHUZHI_MOTOR_SPEED_600].get_to(snp.chu_motor_speed_600);
|
||||
else
|
||||
snp.chu_motor_speed_600 = 100;
|
||||
|
||||
// printf("vid = %d pid =%d \n",snp.Vid,snp.Pid );
|
||||
m_mem_param = snp;
|
||||
return snp;
|
||||
}
|
||||
|
||||
ScannerNativeParam jsonconfig::getdefaultscannerinfo()
|
||||
{
|
||||
ScannerNativeParam param;
|
||||
param.DoubleFeedTimes = 0;
|
||||
param.FeedErrorTimes = 0;
|
||||
param.H_ratio = 1065353216;
|
||||
param.V_ratio = 1065353216;
|
||||
param.JamTimes = 0;
|
||||
param.RollerNum = param.TotalScanned = 0;
|
||||
param.Token = "abcdefghijklmnopqrstuvwxyz012345"; // default 32byte length
|
||||
param.SerialNum = SERIALNUM;
|
||||
#ifdef G200
|
||||
param.gray_sp = 0x775; // G200 140 ppm 0x27c 0x775 G100 100 ppm 0x2B6 0x822
|
||||
param.color_sp = 0x27C;
|
||||
param.speedmode = 100;
|
||||
param.Pid = 0x0239;
|
||||
#else
|
||||
param.gray_sp = 0x822; // G200 140 ppm 0x27c 0x781 G100 100 ppm 0x2B6 0x822
|
||||
param.color_sp = 0x2B6;
|
||||
param.speedmode = 70;
|
||||
param.Pid = 0x0139;
|
||||
#endif
|
||||
param.Vid = 0x3072;
|
||||
param.sleeptime = 10800;
|
||||
param.clr_maxbright = param.gray_maxbright = 200;
|
||||
param.chu_motor_speed_200 = 300;
|
||||
param.chu_motor_speed_300 = 200;
|
||||
param.chu_motor_speed_600 = 100;
|
||||
return param;
|
||||
}
|
||||
|
||||
ScannerNativeParam jsonconfig::getmemparam()
|
||||
{
|
||||
return m_mem_param;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
#include "json.hpp"
|
||||
#include "commondef.h"
|
||||
#include <mutex>
|
||||
using json = nlohmann::json;
|
||||
|
||||
class jsonconfig
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
ScannerNativeParam m_mem_param;
|
||||
public:
|
||||
jsonconfig(/* args */);
|
||||
~jsonconfig();
|
||||
|
||||
void savecisconfig(HGCorrectConfigs configs);
|
||||
void savescannerinfo(ScannerNativeParam scannerinfo);
|
||||
HGCorrectConfigs getcorrectconfigs();
|
||||
ScannerNativeParam getscannerinfo();
|
||||
HGCorrectConfigs getdefaultconfigs();
|
||||
ScannerNativeParam getdefaultscannerinfo();
|
||||
ScannerNativeParam getmemparam();
|
||||
std::mutex mtx;
|
||||
};
|
||||
|
||||
extern jsonconfig m_static_jsonconfig;
|
||||
|
||||
static jsonconfig& Get_static_jsonconfig()
|
||||
{
|
||||
return m_static_jsonconfig;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
#pragma once
|
||||
#include <sstream>
|
||||
#include "commondef.h"
|
||||
enum class SysType
|
||||
{
|
||||
Sys_Linux_Debian = 1,
|
||||
Sys_Linux_Uos,
|
||||
Sys_Android
|
||||
};
|
||||
|
||||
enum class Scanner_Serial
|
||||
{
|
||||
S_G100 = 1,
|
||||
S_G200,
|
||||
S_G300,
|
||||
S_G300_UV,
|
||||
S_G400
|
||||
};
|
||||
|
||||
enum class SCPU
|
||||
{
|
||||
CPU_3288 = 1,
|
||||
CPU_3399
|
||||
};
|
||||
|
||||
enum class SMBType
|
||||
{
|
||||
MB_DRV_UNKNOWUN,
|
||||
MB_DRV_8825,
|
||||
MB_DRV_TMC216,
|
||||
MB_DRV_ANLU,
|
||||
MB_DRV_LATIACE
|
||||
};
|
||||
|
||||
enum class HGCISType
|
||||
{
|
||||
CIS_UNKOWNUN,
|
||||
CIS_HUALIN_MONO_V0,
|
||||
CIS_DUNNAN_MONO_V0,
|
||||
CIS_DUNNAN_COLOR_V0
|
||||
};
|
||||
|
||||
enum class ScreenType
|
||||
{
|
||||
ST_None = 1,
|
||||
ST_SmallLcd,
|
||||
ST_BigLcd,
|
||||
ST_8Inch,
|
||||
ST_7Inch
|
||||
};
|
||||
|
||||
typedef struct Scanner_SysInfo
|
||||
{
|
||||
SCPU CPU; // 3288 3399
|
||||
SysType Systype;
|
||||
ScreenType Screentype;
|
||||
unsigned int MtBoardVersion;
|
||||
SMBType MtType;
|
||||
unsigned int FPGAVersion;
|
||||
HGCISType Cistype;
|
||||
unsigned int ResSup[3]; // 分辨率支持
|
||||
unsigned int MemTotal; // 单位 MB
|
||||
unsigned int DiskTotal; // 单位 MB
|
||||
unsigned int DiskUsed; // 已使用空间
|
||||
std::string KernelVersion;
|
||||
unsigned int Have_EthernPort;
|
||||
std::string ServiceVersion;
|
||||
float UsbProtocol; // 1.0 2.0 2.xx
|
||||
} ScannerSysInfo;
|
|
@ -0,0 +1,165 @@
|
|||
2021年7月12日
|
||||
固件版本号:G139210712
|
||||
第一版程序
|
||||
1.解决配置fpga 增益异常问题;
|
||||
2.增加校正功能;
|
||||
3.基本打通基础功能流程;
|
||||
|
||||
2021年7月15日
|
||||
固件版本号:G139210715
|
||||
修改说明:
|
||||
1.彩色灰度分两步校正,避免校正时颜色模式切换导致的采图异常;
|
||||
2.修复灰度校正过程中,明场背面亮度无法提高问题;
|
||||
3.修复扫描报双张、卡纸,图像上传问题;
|
||||
4.修复报双张、卡纸,未触发PC通知问题;
|
||||
5.修复扫描结束报开盖异常,双张报开盖问题;
|
||||
6.解决usb jpeg buffer传输一位图,解压后图像引入噪点问题;
|
||||
|
||||
2021年7月19日
|
||||
固件版本号:G139210719
|
||||
修改说明:
|
||||
1.解决传输一位图卡死问题
|
||||
2.双张、卡纸等异常交由上层twain处理删除图像数据
|
||||
3.屏蔽notify中的消息发送的等待清除代码
|
||||
4.添加扫描结束stopscan信号上传
|
||||
|
||||
2021年7月21日
|
||||
固件版本号:G139210720
|
||||
1.修复自动校正offset计算时,IC控制的图像条块宽度与计算宽度不一致问题;
|
||||
2.增加fpga固件自动升级功能;
|
||||
3.在获取增加images数据长度时增加images队列数量判断,修复跳过空白页时传入空mat崩溃问题
|
||||
4.屏蔽int 端点 notify 接口while循环导致消息丢失问题;
|
||||
|
||||
2021年9月30日
|
||||
固件版本号:G1392A0930
|
||||
1.修复扫描单张卡纸出图问题
|
||||
2.增加G100 110ppm速度模式
|
||||
3.添加获取ip地址,以及fpga版本功能
|
||||
|
||||
2021年11月17日
|
||||
固件版本号:G1393A1116
|
||||
1.添加折角和尺寸检测到扫描流程
|
||||
2.每次扫描完成后reset fpga
|
||||
3.vid pid可设置
|
||||
4.修改按键休眠不生效问题
|
||||
5.修复600 dpi首张图像丢失问题
|
||||
6.添加数字增益 1.2
|
||||
7.调整usb短时间内拔插导致usbbulk端点阻塞问题
|
||||
|
||||
2022年3月30日
|
||||
固件版本号:G1393B0330
|
||||
1.优化扫描流程,pick_paper放在readframe之前
|
||||
2.添加reload fpga
|
||||
3.更新1.3.12裁切纠偏算法
|
||||
4.修复连续扫描产生的系列问题
|
||||
5.添加带孔扫描
|
||||
6.修复连续扫描下按键操作问题,增加按键停止连续扫描功能
|
||||
7.休眠休眠连续扫描未pc不能关闭问题
|
||||
8.G200 明场最大值调整为200,校正数据上下各裁切50行再进行校正
|
||||
9.修复液晶问题
|
||||
10.调整usb兼容id为600
|
||||
|
||||
2022年7月30日
|
||||
固件版本号:G1393B0730
|
||||
1.添加休眠唤醒接口,添加分纸强度获取设置接口
|
||||
2.添加自动调节分纸强度功能
|
||||
3.更新除穿孔,跳过空白页算法
|
||||
|
||||
|
||||
2022年8月13日
|
||||
1. 电机板FPGA增加托盘档位功能,软件支持设置托盘位置
|
||||
|
||||
2022年9月17日
|
||||
1. 针对通达海调整除穿孔以及跳过空白页算法,除穿孔分为指定上下左右填充避免误填;
|
||||
|
||||
2022年9月27日~2022年10月9日
|
||||
1. 适配3288固件,调整拼接算法,临时解决重影问题,开放自适应幅面
|
||||
2. 配合系统备份功能,USB增加系统备份功能通信指令
|
||||
|
||||
2022年10月19日
|
||||
1. 添加对折模式选择对折方向功能
|
||||
2. 新增设备锁定功能
|
||||
3. 增加清理纸道协议
|
||||
4. 增加0x90002fpga兼容,更新图像拼接算法
|
||||
5. 添加vsp设置功能,默认为2,范围1-20
|
||||
6. 支持不同dpi与颜色模式单独校正
|
||||
7. 添加色偏算法
|
||||
8. 畸变参数由单一参数改为不同dpi不同畸变参数 -22.12.07
|
||||
9. 去掉pickpaper之前的有无纸判断 -22.12.14
|
||||
10.调整休眠唤醒获取接口,由直接读取文件改为获取标志位 -23.01.03
|
||||
11.更新除穿孔算法到1.92版本 -23.01.09
|
||||
12.调整校正,减少校正时间 -23.01.11
|
||||
13.开放填黑框自适应颜色填充 -23.02.21
|
||||
14.除背景色二值化阈值调整为50 (100 - 50) -23.02.21
|
||||
|
||||
2023年3月3日
|
||||
固件版本号:GX393C0303
|
||||
1.修复历史张数清零协议错误问题 -23.03.03
|
||||
2.添加执行shell命令协议 -23.03.03
|
||||
3.添加按键5秒关机动作 -23.03.03
|
||||
4.更新除色,除摩尔纹算法 -23.03.11
|
||||
5.适配9000afpga,vsp调整为75,80 -23.03.11
|
||||
6.更新色偏矫正算法
|
||||
7.调整9000a版本vsp为80,120 -23.04.15
|
||||
8.脱胶版本 默认开启亮度锐化 -23.04.18
|
||||
9.除色散算法更新到v2.0版本 -23.04.18
|
||||
10.调整脱焦 锐化 参数 -23.04.25
|
||||
11.增加慢速除摩尔纹配置,开启后200 300 dpi,扫描应用110ppm 300dpi sp、80ppm 300dpi电机速度,再缩放至指定幅面 -23.05.10
|
||||
12.休眠唤醒调整,长按3秒关机,短按0.2s唤醒,去掉按键休眠功能 -23.05.13
|
||||
13.增加9000b版本fpga兼容 -23.05.13
|
||||
14.去掉MonoCapturer构造函数内的fpga—reset和reset-adc -23.05.15
|
||||
15.更新色偏矫正算法到2.0版本,调整9000b版本拼接算法 -23.05.15
|
||||
16.更新穿孔算法到1.93版本 -23.05.16
|
||||
17.修复不扫描不休眠问题 -23.05.18
|
||||
18.图像处理线程由6调整为4,除色散算法回退到1.30版本 -23.05.18
|
||||
19.调整休眠回调异常崩溃问题 -23.05.18
|
||||
20.调整自动分纸强度不生效问题 -23.05.25
|
||||
21.自适应幅面最小高度调整为A4横向 --23.05.31
|
||||
22.调整校正使用暗场最小值大于0 均值小于25的方式校正,校正前将offset全部重新设置成默认值 --23.06.05
|
||||
|
||||
2023年6月16日
|
||||
固件版本号:GX393C0518
|
||||
1.调整加入灰阶校正方案,新加校正复原功能 --23.06.16
|
||||
2.调整算法,默认使用红色增强plus --23.06.16
|
||||
3.调整除网文算法使用CImageApplyFilter,屏蔽除摩尔纹算法 --23.06.17
|
||||
4.修复休眠时崩溃问题,调整编译器优化选项 --23.07.11
|
||||
5.调整文件传输usb协议,限制固定范围内可读写 --23.07.11
|
||||
6.增加一件备份还原huago文件夹协议 --23.07.11
|
||||
7.增加G100 100ppm速度兼容,设置速度时默认重新设置摩尔纹模式sp --23.07.13
|
||||
8.修改开盖与无纸显示优先级 --23.07.13
|
||||
9.更新除色与颜色增强算法 --23.08.01
|
||||
10.增加灰阶校正配置使能功能,initlut调整 --23.08.29
|
||||
11.调整自定义裁切执行顺序,放在缩放之后 --23.08.29
|
||||
12.添加syslog日志输出 --23.09.26
|
||||
|
||||
|
||||
2023年10月07日
|
||||
固件版本号:GX393C1007
|
||||
1.增加G200 90ppm速度模式 --23.10.07
|
||||
2.增加双张出纸口过纸使能 --23.10.07
|
||||
3.增加液晶面板滚轴张数操作 --23.10.07
|
||||
4.int端点增加扫描张数信息、异常信息 --23.10.11
|
||||
5.增加镜头脏污检测功能 --23.10.16
|
||||
6.调整vsp寄存器配置 8 bit-> 9bit --23.10.17
|
||||
7.使用全局变量统一读写json --23.10.23
|
||||
8.流程调整,提速 --23.10.23
|
||||
9.增加获取或设置片上时间功能 --23.10.25
|
||||
10.基于文件大小跳过空白页 --23.11.03
|
||||
11.修复双张校验异常提示取图失败问题 --23.11.16
|
||||
12.调整旋转对折方式 --23.11.17
|
||||
13.适配9000c版本,修复拼缝问题,fpga增加采集过滤功能 --23.11.17
|
||||
14.增加pick_paper校验 --23.11.22
|
||||
15.修复文件拷贝时未加f参数导致未成功备份问题 --23.11.23
|
||||
16.调整脏污检测与待纸扫描异常提示问题 --23.11.30
|
||||
17.调整200dpi 灰度时缩放算法参数 由双线性插值改为区域均值 --23.11.30
|
||||
18.调整双张图像上传与跳过空白页算法逻辑 --23.12.05
|
||||
19.更新脏污检测算法 --23.12.06
|
||||
20.更新算法 跳过空白页 ->1.91
|
||||
穿孔算法 -> 1.11
|
||||
答题卡除红 ->1.54
|
||||
防渗透算法 ->3.1 --23.12.06
|
||||
21.更新裁切纠偏 除穿孔算法,分离除色散算法 --23.12.08
|
||||
22.修复G200 代码脏污检测报错再结束中断之前问题 --23.12.08
|
||||
23.调整跳过空白页到亮度、对比度算法之后 --23.12.08
|
||||
24.G100按键液晶增加耗材查询功能 --23.12.11
|
||||
25.屏蔽灰度除色散算法 --23.12.11
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#define FPGA_UART "/dev/ttyUSB0"
|
||||
#define MOTOR_UART "/dev/ttyS4"
|
||||
/* #undef CIS_TYPE */
|
||||
/* #undef TEST_IMAGE_DIR */
|
||||
/* #undef CAP_UNFIXED */
|
||||
#define TEST_FPGA "ON"
|
||||
/* #undef LOOP_DEBUG */
|
||||
#define VIDEO_CLASS GVideoISP1
|
|
@ -0,0 +1,16 @@
|
|||
project(deviceio)
|
||||
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}/../packages/common.pkg/include
|
||||
)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
|
|
@ -0,0 +1,32 @@
|
|||
#include "DevUtil.h"
|
||||
#include <fstream>
|
||||
#include "stringex.hpp"
|
||||
|
||||
#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,94 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
#define G300
|
||||
|
||||
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 PORTS
|
||||
{
|
||||
Start = 171,
|
||||
Stop = 49,
|
||||
Power = 5,
|
||||
Fpga_Load = 70,
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
class DeviceExport
|
||||
{
|
||||
public:
|
||||
DeviceExport();
|
||||
|
||||
private:
|
||||
#ifndef G300
|
||||
const int ports[38] = {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};
|
||||
#else
|
||||
const int ports[36] = {Start, Stop, Power, Fpga_Load, MotorPower, CuoZhiMotor_Reset, CuoZhiMotor_Sleep, CuoZhiMotor_Enable,
|
||||
CuoZhiMotor_Direction, CuoZhiMotor_Decay, CuoZhiMotor_Home, CuoZhiMotor_Fault, CuoZhiMotor_Mode0,
|
||||
CuoZhiMotor_Mode1, CuoZhiMotor_Mode2, Cover, Paper, Scan, 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};
|
||||
#endif
|
||||
const int pwms[2] = {2, 3};
|
||||
};
|
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// Created by yingluo907 on 2019/4/11.
|
||||
//
|
||||
#include "Gpio.h"
|
||||
#include "DevUtil.h"
|
||||
#include "stringex.hpp"
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <fcntl.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());
|
||||
char fpath[128]{};
|
||||
sprintf(fpath, "/sys/class/gpio/gpio%d/value", port);
|
||||
printf("Gpio::Gpio(int port = %d) \n", port);
|
||||
gpio_fd = open(fpath, O_RDWR);
|
||||
}
|
||||
|
||||
Gpio::~Gpio()
|
||||
{
|
||||
close(gpio_fd);
|
||||
}
|
||||
int Gpio::getPort()
|
||||
{
|
||||
return port;
|
||||
}
|
||||
|
||||
void Gpio::setValue(GpioLevel level)
|
||||
{
|
||||
// write_dev(path_value, level);
|
||||
if (port == 153 || port == 150)
|
||||
printf("\n Gpio %d setvalue %d ", port, level == Low ? 0 : 1);
|
||||
if (level == Low)
|
||||
write(gpio_fd, "0\n", 2);
|
||||
else
|
||||
write(gpio_fd, "1\n", 2);
|
||||
}
|
||||
|
||||
Gpio::GpioLevel Gpio::getValue()
|
||||
{
|
||||
return (Gpio::GpioLevel)read_dev_i(path_value);
|
||||
}
|
||||
|
||||
std::string Gpio::getDirection()
|
||||
{
|
||||
return read_dev_s(path_direction);
|
||||
}
|
||||
|
||||
void Gpio::setDirection(std::string direction)
|
||||
{
|
||||
if (port == 153 || port == 150)
|
||||
printf("\n Gpio %d setDirection %s ", port, direction.c_str());
|
||||
write_dev(path_direction, direction);
|
||||
}
|
||||
|
||||
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,52 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
|
||||
class Gpio
|
||||
{
|
||||
public:
|
||||
enum GpioLevel
|
||||
{
|
||||
Low,
|
||||
High
|
||||
};
|
||||
|
||||
Gpio(int port);
|
||||
~Gpio();
|
||||
int getPort();
|
||||
void setValue(GpioLevel level);
|
||||
GpioLevel getValue();
|
||||
std::string getDirection();
|
||||
void setDirection(std::string direction);
|
||||
void setActive(GpioLevel level);
|
||||
GpioLevel getActive();
|
||||
void setEdge(std::string edge);
|
||||
std::string getEdge();
|
||||
|
||||
std::string getValuePath()
|
||||
{
|
||||
return path_value;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
int port;
|
||||
const std::string path_gpiobase = "/sys/class/gpio";
|
||||
std::string path_value = "value";
|
||||
std::string path_edge = "edge";
|
||||
std::string path_direction = "direction";
|
||||
std::string path_active_low = "active_low";
|
||||
int gpio_fd;
|
||||
};
|
||||
|
||||
class GpioOut : public Gpio
|
||||
{
|
||||
public:
|
||||
GpioOut(int port);
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
#include "Led.h"
|
||||
#include "stringex.hpp"
|
||||
|
||||
#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,76 @@
|
|||
#include "PinMonitor.h"
|
||||
#include "DevUtil.h"
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
#include "StopWatch.h"
|
||||
|
||||
PinMonitor::PinMonitor(unsigned int pinNum, std::function<void(int)> call_back)
|
||||
: pin(pinNum)
|
||||
{
|
||||
pin.setDirection(Gpio::in);
|
||||
pin.setEdge(Gpio::falling);
|
||||
this->call_back = call_back;
|
||||
thread_monitor = std::thread(&PinMonitor::monitor, this);
|
||||
// printf("PinMonitor threadid = %d \n",thread_monitor.get_id());
|
||||
}
|
||||
|
||||
PinMonitor::~PinMonitor()
|
||||
{
|
||||
bMonitor = false;
|
||||
if (thread_monitor.joinable())
|
||||
thread_monitor.join();
|
||||
}
|
||||
|
||||
void PinMonitor::monitor()
|
||||
{
|
||||
pollfd pfd;
|
||||
int ret = 0;
|
||||
pfd.fd = -1;
|
||||
char buf[8];
|
||||
int num;
|
||||
StopWatch sw;
|
||||
|
||||
pfd.fd = open(pin.getValuePath().c_str(), O_RDONLY);
|
||||
if (pfd.fd < 0)
|
||||
ret = -1;
|
||||
|
||||
pfd.events = POLLPRI;
|
||||
num = read(pfd.fd, buf, 8); // This is to clear the avaible read
|
||||
|
||||
while (bMonitor)
|
||||
{
|
||||
ret = poll(&pfd, 1, 1000);
|
||||
if (ret > 0)
|
||||
{
|
||||
if (pfd.revents & POLLPRI)
|
||||
{
|
||||
lseek(pfd.fd, 0, SEEK_SET);
|
||||
num = read(pfd.fd, buf, 8);
|
||||
|
||||
buf[num - 1] = '\0';
|
||||
ret = atoi(buf);
|
||||
|
||||
if (call_back)
|
||||
call_back(pin.getPort());
|
||||
|
||||
sw.reset();
|
||||
while (sw.elapsed_ms() < 30)
|
||||
{
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include "Gpio.h"
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
|
||||
class PinMonitor
|
||||
{
|
||||
public:
|
||||
PinMonitor(unsigned int pinNum, std::function<void(int)> call_back);
|
||||
~PinMonitor();
|
||||
|
||||
private:
|
||||
void monitor();
|
||||
|
||||
Gpio pin;
|
||||
std::function<void(unsigned int)> call_back;
|
||||
std::thread thread_monitor;
|
||||
volatile bool bMonitor = true;
|
||||
};
|
|
@ -0,0 +1,38 @@
|
|||
#include "Pwm.h"
|
||||
#include "DevUtil.h"
|
||||
#include "stringex.hpp"
|
||||
|
||||
#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,8 @@
|
|||
add_rules("mode.debug", "mode.release")
|
||||
|
||||
target("deviceio")
|
||||
set_kind("static")
|
||||
add_syslinks("pthread")
|
||||
add_files("*.cpp")
|
||||
add_includedirs(".", { public = true})
|
||||
add_packages("common")
|
|
@ -0,0 +1,18 @@
|
|||
project(display)
|
||||
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}/../packages/common.pkg/include
|
||||
${PROJECT_SOURCE_DIR}/../deviceio
|
||||
${PROJECT_SOURCE_DIR}/../capimage
|
||||
)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
|
|
@ -0,0 +1,61 @@
|
|||
#include "DisplayCenter.h"
|
||||
#include "deviceconfig.h"
|
||||
|
||||
DisplayCenter::DisplayCenter():m_lcd(new LCDDisplay(Get_static_deviceconfig().GetParam().language))
|
||||
,brun(false)
|
||||
{
|
||||
m_showthread.reset(new std::thread(&DisplayCenter::runloop,this));
|
||||
m_distype = DisType::Dis_Idel;
|
||||
}
|
||||
|
||||
DisplayCenter::~DisplayCenter()
|
||||
{
|
||||
brun = false;
|
||||
if(m_showthread.get()&& m_showthread->joinable())
|
||||
{
|
||||
m_showthread->join();
|
||||
m_showthread.reset();
|
||||
}
|
||||
|
||||
if(!m_msgs.IsShutDown())
|
||||
m_msgs.ShutDown();
|
||||
|
||||
m_lcd.reset();
|
||||
}
|
||||
|
||||
void DisplayCenter::PutMsg(DisType distype,int pagenum,ClearScreen clearscreen)
|
||||
{
|
||||
m_msgs.Put({distype,clearscreen,(unsigned int )pagenum,""});
|
||||
m_distype = distype;
|
||||
printf("\n ----- distype = %d ",distype);
|
||||
}
|
||||
|
||||
void DisplayCenter::ResetMsgQueue()
|
||||
{
|
||||
m_msgs.Clear();
|
||||
}
|
||||
|
||||
void DisplayCenter::runloop()
|
||||
{
|
||||
brun = true;
|
||||
while (brun)
|
||||
{
|
||||
if(m_msgs.Size()>0)
|
||||
{
|
||||
auto msg= m_msgs.Take();
|
||||
m_lcd->DisplayState(msg.distype,msg.pagenum,msg.clearscree);
|
||||
}
|
||||
else
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||
}
|
||||
}
|
||||
|
||||
DisType DisplayCenter::getcurdistype()
|
||||
{
|
||||
return m_distype;
|
||||
}
|
||||
|
||||
void DisplayCenter::set_language(LCDDisplay::Language language)
|
||||
{
|
||||
if(m_lcd.get()) m_lcd->set_language(language);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
#include "BlockingQueue.h"
|
||||
#include "Displaydef.h"
|
||||
#include "LCDDisplay.h"
|
||||
|
||||
class DisplayCenter
|
||||
{
|
||||
public:
|
||||
DisplayCenter();
|
||||
~DisplayCenter();
|
||||
void PutMsg(DisType distype,int pagenum,ClearScreen clearscreen);
|
||||
void ResetMsgQueue();
|
||||
void set_language(LCDDisplay::Language language);
|
||||
DisType getcurdistype();
|
||||
private:
|
||||
struct MsgPair{
|
||||
DisType distype;
|
||||
ClearScreen clearscree;
|
||||
unsigned int pagenum;
|
||||
std::string infomsg;
|
||||
};
|
||||
void runloop();
|
||||
private:
|
||||
BlockingQueue<MsgPair> m_msgs;
|
||||
std::shared_ptr<std::thread> m_showthread;
|
||||
std::shared_ptr<LCDDisplay> m_lcd;
|
||||
volatile DisType m_distype;
|
||||
bool brun;
|
||||
};
|
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "HgLCDfont.h"
|
||||
|
||||
enum class DisType{
|
||||
Dis_Unkown,
|
||||
Dis_Init,//启动欢迎界面
|
||||
Dis_Welcome,
|
||||
Dis_Idel,//就绪
|
||||
Dis_Scan,
|
||||
Dis_Err_JamIn,
|
||||
Dis_Err_DoubleFeed,
|
||||
Dis_Err_PaperScrew,
|
||||
Dis_Err_Stable,
|
||||
Dis_Err_AqrImgTimeout,
|
||||
Dis_Err_CoverOpen,
|
||||
Dis_Err_JamOut,
|
||||
Dis_Err_HandModeJam,
|
||||
Dis_Err_FeedError,
|
||||
Dis_Err_NoPaper,
|
||||
Dis_Err_DogEar,
|
||||
Dis_Err_Size,
|
||||
Dis_Set_PollPaperIntensity,
|
||||
Dis_Set_PollPI_High,
|
||||
Dis_Set_PollPI_Mid,
|
||||
Dis_Set_PollPI_Low,
|
||||
Dis_Count_Page,
|
||||
Dis_Scan_Page,
|
||||
Dis_Set_ClearPaperPass,
|
||||
Dis_Set_Count,
|
||||
Dis_Set_SleepMode,
|
||||
Dis_Set_SleepMode_5M,
|
||||
Dis_Set_SleepMode_10M,
|
||||
Dis_Set_SleepMode_20M,
|
||||
Dis_Set_SleepMode_30M,
|
||||
Dis_Set_SleepMode_1H,
|
||||
Dis_Set_SleepMode_2H,
|
||||
Dis_Set_SleepMode_4H,
|
||||
Dis_Set_SleepMode_NEVER,
|
||||
Dis_Set_Poweroff,
|
||||
Dis_Set_Return,
|
||||
Dis_HandMode,
|
||||
Dis_Set_Item_Return,
|
||||
Dis_Set_TrayPosition,
|
||||
Dis_Set_TrayPosition_Low,
|
||||
Dis_Set_TrayPosition_Mid,
|
||||
Dis_Set_TrayPosition_High,
|
||||
Dis_Device_Lock,
|
||||
Dis_Set_ScanNum_Option,
|
||||
Dis_Set_Get_History_ScanNum,
|
||||
Dis_Set_Clear_Roller_ScanNum,
|
||||
Dis_Set_Get_Roller_ScanNum,
|
||||
Dis_Set_Is_Sure,
|
||||
Dis_Set_YES,
|
||||
Dis_Set_No,
|
||||
Dis_Language,
|
||||
Dis_Language_Chinese,
|
||||
Dis_Language_Chinese_Traditional,
|
||||
Dis_Language_English,
|
||||
};
|
||||
|
||||
enum class DisDrawtype
|
||||
{
|
||||
DD_All,
|
||||
DD_TopLeft,
|
||||
DD_BotRight
|
||||
};
|
||||
|
||||
enum class ClearScreen
|
||||
{
|
||||
All,
|
||||
TOP,
|
||||
BOT,
|
||||
};
|
||||
|
||||
struct DisInfo{
|
||||
unsigned char page;
|
||||
unsigned char col;
|
||||
DisDrawtype drawtype;
|
||||
std::vector<unsigned char> str;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,189 @@
|
|||
#include "LCDDisplay.h"
|
||||
#include "Lcd.h"
|
||||
#include <StopWatch.h>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include "stringex.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
LCDDisplay::LCDDisplay(int language)
|
||||
{
|
||||
if(language >=0 && language < 3)
|
||||
m_language = (LCDDisplay::Language)language;
|
||||
else
|
||||
m_language = LCDDisplay::Language::Chinese;
|
||||
lcd.reset(new Lcd());
|
||||
lcd->Lcd_Initial_Lcd(false);
|
||||
map_Display = {map_Display_CN,map_Display_TC,map_Display_EN};
|
||||
// lcd->Lcd_Clear_screen();
|
||||
// lcd->Lcd_Display_Graphic_16x16(map_Display[DisType::Dis_Init].page, map_Display[DisType::Dis_Init].col, map_Display[DisType::Dis_Init].str.data(),map_Display[DisType::Dis_Init].str.size()/32);
|
||||
}
|
||||
|
||||
LCDDisplay::~LCDDisplay()
|
||||
{
|
||||
lcd->Lcd_Clear_screen();
|
||||
lcd.reset();
|
||||
}
|
||||
|
||||
void LCDDisplay::DisplayState(DisType ds, unsigned int pagenum,ClearScreen clearscree)
|
||||
{
|
||||
if(clearscree == ClearScreen::All)
|
||||
lcd->Lcd_Clear_screen();
|
||||
if(clearscree == ClearScreen::TOP)
|
||||
lcd->Lcd_Clear_Half_Screen(true);
|
||||
if(clearscree == ClearScreen::BOT)
|
||||
lcd->Lcd_Clear_Half_Screen(false);
|
||||
if (map_Display[m_language_map[m_language]].count(ds) > 0)
|
||||
{
|
||||
m_status = ds;
|
||||
StopWatch sw;
|
||||
auto dsinfo = map_Display[m_language_map[m_language]][ds];
|
||||
if (ds == DisType::Dis_Welcome)//show logo
|
||||
{
|
||||
lcd->Lcd_Display_Graphic_128x64(dsinfo.page, dsinfo.col, dsinfo.str.data());
|
||||
}
|
||||
else if(ds == DisType::Dis_Language_Chinese || ds == DisType::Dis_Language_Chinese_Traditional)
|
||||
{
|
||||
lcd->Lcd_Display_Graphic_16x16(dsinfo.page, dsinfo.col, dsinfo.str.data(), dsinfo.str.size() / 32);
|
||||
}
|
||||
else if(ds == DisType::Dis_Language_English)
|
||||
lcd->Lcd_Display_String_8x16(dsinfo.page, dsinfo.col, (const char*)dsinfo.str.data());
|
||||
else
|
||||
{
|
||||
if(m_language == Language::English)
|
||||
lcd->Lcd_Display_String_8x16(dsinfo.page, dsinfo.col, (const char*)dsinfo.str.data());
|
||||
else
|
||||
lcd->Lcd_Display_Graphic_16x16(dsinfo.page, dsinfo.col, dsinfo.str.data(), dsinfo.str.size() / 32);
|
||||
//lcd->Lcd_Display_String_8x16(dsinfo.page, dsinfo.col, (const char*)dsinfo.str.data());
|
||||
//if (ds == DisType::Dis_Scan || ds == DisType::Dis_Set_Count) //扫描或者计数 更新下半部分内容
|
||||
//{
|
||||
//lcd->Lcd_Clear_Half_Screen(false);
|
||||
//lcd->Lcd_Display_String_8x16(3, 96, "0");
|
||||
//lcd->Lcd_Display_Graphic_16x16(map_Display[DisType::Dis_Scan_Page].page, map_Display[DisType::Dis_Scan_Page].col, map_Display[DisType::Dis_Scan_Page].str.data(), map_Display[DisType::Dis_Scan_Page].str.size() / 32);
|
||||
//}
|
||||
}
|
||||
|
||||
switch (ds)
|
||||
{
|
||||
case DisType::Dis_Count_Page:
|
||||
case DisType::Dis_Scan_Page:
|
||||
{
|
||||
//std::string val = std::to_string(pagenum);
|
||||
//auto offsetdot = bitnum(pagenum) - 1;
|
||||
std::string val = string_format("%04d",pagenum);
|
||||
int offsetdot = val.length();
|
||||
//printf("\n val = %s lenght = %d",val.c_str(),val.size());
|
||||
lcd->Lcd_Display_String_8x16(3, 112 - offsetdot * 8, val.c_str()); //8 -> 一个数字所占点个数宽度
|
||||
lcd->Lcd_Display_Graphic_16x16(map_Display[m_language_map[m_language]][DisType::Dis_Scan_Page].page, map_Display[m_language_map[m_language]][DisType::Dis_Scan_Page].col,
|
||||
map_Display[m_language_map[m_language]][DisType::Dis_Scan_Page].str.data(), map_Display[m_language_map[m_language]][DisType::Dis_Scan_Page].str.size() / 32);
|
||||
break;
|
||||
}
|
||||
case DisType::Dis_Err_JamIn:
|
||||
{
|
||||
if(pagenum == 1)
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "P a 1 0 1"); //8 -> 一个数字所占点个数宽度
|
||||
else if(pagenum == 2)
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "P a 1 0 2");
|
||||
else if(pagenum == 3)
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "P a 1 0 3");
|
||||
break;
|
||||
}
|
||||
case DisType::Dis_Err_AqrImgTimeout:
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "G p 0 0 1");
|
||||
break;
|
||||
case DisType::Dis_Err_CoverOpen:
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "C o 0 0 1");
|
||||
break;
|
||||
case DisType::Dis_Err_PaperScrew:
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "S K 0 0 1");
|
||||
break;
|
||||
case DisType::Dis_Err_DoubleFeed:
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "D b 0 0 1");
|
||||
break;
|
||||
case DisType::Dis_Err_NoPaper:
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "N o 0 0 1");
|
||||
break;
|
||||
case DisType::Dis_Err_Stable:
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "S T 0 0 1");
|
||||
break;
|
||||
case DisType::Dis_Err_FeedError:
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "P f 0 0 1");
|
||||
break;
|
||||
case DisType::Dis_Err_DogEar:
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "Z J 0 0 1");
|
||||
break;
|
||||
case DisType::Dis_Err_Size:
|
||||
lcd->Lcd_Display_String_8x16(3, 56, "C C 0 0 1");
|
||||
break;
|
||||
case DisType::Dis_Set_Get_History_ScanNum:
|
||||
{
|
||||
std::string val = std::to_string(pagenum);
|
||||
int offsetdot = 8 > val.length() ? val.length() : 8;
|
||||
lcd->Lcd_Display_String_8x16(3, 128 - offsetdot * 8, val.c_str()); //8 -> 一个数字所占点个数宽度
|
||||
break;
|
||||
}
|
||||
case DisType::Dis_Set_Get_Roller_ScanNum:
|
||||
{
|
||||
std::string val = std::to_string(pagenum);
|
||||
int offsetdot = 8 > val.length() ? val.length() : 8;
|
||||
lcd->Lcd_Display_String_8x16(3, 128 - offsetdot * 8, val.c_str()); //8 -> 一个数字所占点个数宽度
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ds){
|
||||
case DisType::Dis_Set_SleepMode_5M:
|
||||
lcd->Lcd_Display_String_8x16(3, 112, "5M");
|
||||
break;
|
||||
case DisType::Dis_Set_SleepMode_10M:
|
||||
lcd->Lcd_Display_String_8x16(3, 104, "10M");
|
||||
break;
|
||||
case DisType::Dis_Set_SleepMode_20M:
|
||||
lcd->Lcd_Display_String_8x16(3, 104, "20M");
|
||||
break;
|
||||
case DisType::Dis_Set_SleepMode_30M:
|
||||
lcd->Lcd_Display_String_8x16(3, 104, "30M");
|
||||
break;
|
||||
case DisType::Dis_Set_SleepMode_1H:
|
||||
lcd->Lcd_Display_String_8x16(3, 112, "1H");
|
||||
break;
|
||||
case DisType::Dis_Set_SleepMode_2H:
|
||||
lcd->Lcd_Display_String_8x16(3, 112, "2H");
|
||||
break;
|
||||
case DisType::Dis_Set_SleepMode_4H:
|
||||
lcd->Lcd_Display_String_8x16(3, 112, "4H");
|
||||
break;
|
||||
default:
|
||||
m_status= DisType::Dis_Unkown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int LCDDisplay::bitnum(unsigned int num)
|
||||
{
|
||||
int count = 0;
|
||||
do
|
||||
{
|
||||
num = num / 10;
|
||||
count++;
|
||||
} while (num > 0);
|
||||
return count;
|
||||
}
|
||||
|
||||
DisType LCDDisplay::GetCurrentStatus() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
void LCDDisplay::set_language(Language language)
|
||||
{
|
||||
if(language != m_language)
|
||||
m_language = language;
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
#pragma once
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "Displaydef.h"
|
||||
|
||||
class Lcd;
|
||||
|
||||
class LCDDisplay
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
enum Language
|
||||
{
|
||||
Chinese,
|
||||
TraditionalChinese,
|
||||
English,
|
||||
};
|
||||
|
||||
LCDDisplay(int language);
|
||||
~LCDDisplay();
|
||||
void set_language(Language language);
|
||||
void DisplayState(DisType ds,unsigned int pagenum,ClearScreen clearscree);
|
||||
DisType GetCurrentStatus() const;
|
||||
|
||||
private:
|
||||
|
||||
int bitnum(unsigned int num);
|
||||
|
||||
private:
|
||||
std::vector<std::map<DisType,DisInfo>> map_Display;
|
||||
std::shared_ptr<Lcd> lcd;
|
||||
Language m_language;
|
||||
DisType m_status;
|
||||
|
||||
std::map<Language,int> m_language_map{
|
||||
{Language::Chinese,0},
|
||||
{Language::TraditionalChinese,1},
|
||||
{Language::English,2},
|
||||
};
|
||||
|
||||
|
||||
std::map<DisType,DisInfo> map_Display_CN={
|
||||
{DisType::Dis_Welcome,{1,1,DisDrawtype::DD_All,std::vector<unsigned char>(f_logo,f_logo+sizeof(f_logo))}},
|
||||
{DisType::Dis_Init,{1,1,DisDrawtype::DD_All,std::vector<unsigned char>(f_welcome,f_welcome+sizeof(f_welcome))}},
|
||||
{DisType::Dis_Idel,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_ready,f_ready+sizeof(f_ready))}},
|
||||
{DisType::Dis_Scan,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_scan,f_scan+sizeof(f_scan))}},
|
||||
{DisType::Dis_Set_ClearPaperPass,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_clearpaperpass,f_clearpaperpass+sizeof(f_clearpaperpass))}},
|
||||
{DisType::Dis_Set_Count,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_countmode,f_countmode+sizeof(f_countmode))}},
|
||||
{DisType::Dis_Err_DoubleFeed,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_doublefeed,f_doublefeed+sizeof(f_doublefeed))}},
|
||||
{DisType::Dis_Err_Stable,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_stable,f_stable+sizeof(f_stable))}},
|
||||
{DisType::Dis_Err_CoverOpen,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_coveropen,f_coveropen+sizeof(f_coveropen))}},
|
||||
{DisType::Dis_Err_JamIn,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_paperjam,f_paperjam+sizeof(f_paperjam))}},
|
||||
{DisType::Dis_Err_JamOut,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_paperjam,f_paperjam+sizeof(f_paperjam))}},
|
||||
{DisType::Dis_Err_HandModeJam,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_handmodepaperjam,f_handmodepaperjam+sizeof(f_handmodepaperjam))}},
|
||||
{DisType::Dis_Err_PaperScrew,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_paperscrew,f_paperscrew+sizeof(f_paperscrew))}},
|
||||
{DisType::Dis_Err_FeedError,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_feederror,f_feederror+sizeof(f_feederror))}},
|
||||
{DisType::Dis_Err_AqrImgTimeout,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_aqrimgtimeout,f_aqrimgtimeout+sizeof(f_aqrimgtimeout))}},
|
||||
{DisType::Dis_Err_DogEar,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_dogear,f_dogear+sizeof(f_dogear))}},
|
||||
{DisType::Dis_Err_Size,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_size,f_size+sizeof(f_size))}},
|
||||
{DisType::Dis_Set_PollPaperIntensity,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_pollpaperintensity,f_pollpaperintensity+sizeof(f_pollpaperintensity))}},
|
||||
{DisType::Dis_Set_PollPI_High,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityHigh,f_intensityHigh+sizeof(f_intensityHigh))}},
|
||||
{DisType::Dis_Set_PollPI_Mid,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityMid,f_intensityMid+sizeof(f_intensityMid))}},
|
||||
{DisType::Dis_Set_PollPI_Low,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityLow,f_intensityLow+sizeof(f_intensityLow))}},
|
||||
|
||||
{DisType::Dis_Set_TrayPosition,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_trayposition,f_trayposition+sizeof(f_trayposition))}},
|
||||
{DisType::Dis_Set_TrayPosition_High,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityHigh,f_intensityHigh+sizeof(f_intensityHigh))}},
|
||||
{DisType::Dis_Set_TrayPosition_Mid,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityMid,f_intensityMid+sizeof(f_intensityMid))}},
|
||||
{DisType::Dis_Set_TrayPosition_Low,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_traypositionLow,f_traypositionLow+sizeof(f_traypositionLow))}},
|
||||
|
||||
{DisType::Dis_Count_Page,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_page,f_page+sizeof(f_page))}},
|
||||
{DisType::Dis_Scan_Page,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_page,f_page+sizeof(f_page))}},
|
||||
{DisType::Dis_Err_NoPaper,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_nopaper,f_nopaper+sizeof(f_nopaper))}},
|
||||
{DisType::Dis_Set_SleepMode,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_sleepmode,f_sleepmode+sizeof(f_sleepmode))}},
|
||||
// {DisType::Dis_Set_SleepMode_30M,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_30min,f_30min+sizeof(f_30min))}},
|
||||
// {DisType::Dis_Set_SleepMode_1H,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_1hour,f_1hour+sizeof(f_1hour))}},
|
||||
// {DisType::Dis_Set_SleepMode_2H,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_2hour,f_2hour+sizeof(f_2hour))}},
|
||||
{DisType::Dis_Set_SleepMode_NEVER,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_never,f_never+sizeof(f_never))}},
|
||||
{DisType::Dis_Set_Return,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_return,f_return+sizeof(f_return))}},
|
||||
{DisType::Dis_Set_Poweroff,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_powerof,f_powerof+sizeof(f_powerof))}},
|
||||
{DisType::Dis_HandMode,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_handmode,f_handmode+sizeof(f_handmode))}},
|
||||
{DisType::Dis_Set_Item_Return,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_return,f_return+sizeof(f_return))}},
|
||||
{DisType::Dis_Device_Lock,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_deviceLock,f_deviceLock+sizeof(f_deviceLock))}},
|
||||
{DisType::Dis_Set_ScanNum_Option,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_scannum,f_scannum+sizeof(f_scannum))}},
|
||||
{DisType::Dis_Set_Get_History_ScanNum,{3,1,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_history_num,f_history_num+sizeof(f_history_num))}},
|
||||
{DisType::Dis_Set_Get_Roller_ScanNum,{3,1,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_roller_num,f_roller_num+sizeof(f_roller_num))}},
|
||||
{DisType::Dis_Set_Clear_Roller_ScanNum,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_clrea_roller,f_clrea_roller+sizeof(f_clrea_roller))}},
|
||||
{DisType::Dis_Set_Is_Sure,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_is_sure,f_is_sure+sizeof(f_is_sure))}},
|
||||
{DisType::Dis_Set_YES,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_yes,f_yes+sizeof(f_yes))}},
|
||||
{DisType::Dis_Set_No,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_no,f_no+sizeof(f_no))}},
|
||||
{DisType::Dis_Language,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_language,f_language+sizeof(f_language))}},
|
||||
{DisType::Dis_Language_Chinese,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_language_chinese,f_language_chinese+sizeof(f_language_chinese))}},
|
||||
{DisType::Dis_Language_Chinese_Traditional,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_language_chinese_traditional,f_language_chinese_traditional+sizeof(f_language_chinese_traditional))}},
|
||||
{DisType::Dis_Language_English,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_language_english,f_language_english+sizeof(f_language_english))}},
|
||||
};
|
||||
|
||||
|
||||
std::map<DisType,DisInfo> map_Display_EN={
|
||||
{DisType::Dis_Welcome,{1,1,DisDrawtype::DD_All,std::vector<unsigned char>(f_logo,f_logo+sizeof(f_logo))}},
|
||||
{DisType::Dis_Init,{1,1,DisDrawtype::DD_All,std::vector<unsigned char>(f_welcome_EN,f_welcome_EN+sizeof(f_welcome_EN))}},
|
||||
{DisType::Dis_Idel,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_ready_EN,f_ready_EN+sizeof(f_ready_EN))}},
|
||||
{DisType::Dis_Scan,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_scan_EN,f_scan_EN+sizeof(f_scan_EN))}},
|
||||
{DisType::Dis_Set_ClearPaperPass,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_clearpaperpass_EN,f_clearpaperpass_EN+sizeof(f_clearpaperpass_EN))}},
|
||||
{DisType::Dis_Set_Count,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_countmode_EN,f_countmode_EN+sizeof(f_countmode_EN))}},
|
||||
{DisType::Dis_Err_DoubleFeed,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_doublefeed_EN,f_doublefeed_EN+sizeof(f_doublefeed_EN))}},
|
||||
{DisType::Dis_Err_Stable,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_stable_EN,f_stable_EN+sizeof(f_stable_EN))}},
|
||||
{DisType::Dis_Err_CoverOpen,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_coveropen_EN,f_coveropen_EN+sizeof(f_coveropen_EN))}},
|
||||
{DisType::Dis_Err_JamIn,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_paperjam_EN,f_paperjam_EN+sizeof(f_paperjam_EN))}},
|
||||
{DisType::Dis_Err_JamOut,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_paperjam_EN,f_paperjam_EN+sizeof(f_paperjam_EN))}},
|
||||
{DisType::Dis_Err_HandModeJam,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_handmodepaperjam_EN,f_handmodepaperjam_EN+sizeof(f_handmodepaperjam_EN))}},
|
||||
{DisType::Dis_Err_PaperScrew,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_paperscrew_EN,f_paperscrew_EN+sizeof(f_paperscrew_EN))}},
|
||||
{DisType::Dis_Err_FeedError,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_feederror_EN,f_feederror_EN+sizeof(f_feederror_EN))}},
|
||||
{DisType::Dis_Err_AqrImgTimeout,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_aqrimgtimeout_EN,f_aqrimgtimeout_EN+sizeof(f_aqrimgtimeout_EN))}},
|
||||
{DisType::Dis_Err_DogEar,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_dogear_EN,f_dogear_EN+sizeof(f_dogear_EN))}},
|
||||
{DisType::Dis_Err_Size,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_size,f_size+sizeof(f_size))}},
|
||||
{DisType::Dis_Set_PollPaperIntensity,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_pollpaperintensity_EN,f_pollpaperintensity_EN+sizeof(f_pollpaperintensity_EN))}},
|
||||
{DisType::Dis_Set_PollPI_High,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityHigh_EN,f_intensityHigh_EN+sizeof(f_intensityHigh_EN))}},
|
||||
{DisType::Dis_Set_PollPI_Mid,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityMid_EN,f_intensityMid_EN+sizeof(f_intensityMid_EN))}},
|
||||
{DisType::Dis_Set_PollPI_Low,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityLow_EN,f_intensityLow_EN+sizeof(f_intensityLow_EN))}},
|
||||
|
||||
{DisType::Dis_Set_TrayPosition,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_trayposition_EN,f_trayposition_EN+sizeof(f_trayposition_EN))}},
|
||||
{DisType::Dis_Set_TrayPosition_High,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityHigh_EN,f_intensityHigh_EN+sizeof(f_intensityHigh_EN))}},
|
||||
{DisType::Dis_Set_TrayPosition_Mid,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityMid_EN,f_intensityMid_EN+sizeof(f_intensityMid_EN))}},
|
||||
{DisType::Dis_Set_TrayPosition_Low,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_traypositionLow_EN,f_traypositionLow_EN+sizeof(f_traypositionLow_EN))}},
|
||||
|
||||
{DisType::Dis_Count_Page,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_page_EN,f_page_EN+sizeof(f_page_EN))}},
|
||||
{DisType::Dis_Scan_Page,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_page_EN,f_page_EN+sizeof(f_page_EN))}},
|
||||
{DisType::Dis_Err_NoPaper,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_nopaper_EN,f_nopaper_EN+sizeof(f_nopaper_EN))}},
|
||||
{DisType::Dis_Set_SleepMode,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_sleepmode_EN,f_sleepmode_EN+sizeof(f_sleepmode_EN))}},
|
||||
// {DisType::Dis_Set_SleepMode_30M,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_30min,f_30min+sizeof(f_30min))}},
|
||||
// {DisType::Dis_Set_SleepMode_1H,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_1hour,f_1hour+sizeof(f_1hour))}},
|
||||
// {DisType::Dis_Set_SleepMode_2H,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_2hour,f_2hour+sizeof(f_2hour))}},
|
||||
{DisType::Dis_Set_SleepMode_NEVER,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_never_EN,f_never_EN+sizeof(f_never_EN))}},
|
||||
{DisType::Dis_Set_Return,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_return_EN,f_return_EN+sizeof(f_return_EN))}},
|
||||
{DisType::Dis_Set_Poweroff,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_powerof_EN,f_powerof_EN+sizeof(f_powerof_EN))}},
|
||||
{DisType::Dis_HandMode,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_handmode_EN,f_handmode_EN+sizeof(f_handmode_EN))}},
|
||||
{DisType::Dis_Set_Item_Return,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_return_EN,f_return_EN+sizeof(f_return_EN))}},
|
||||
{DisType::Dis_Device_Lock,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_deviceLock_EN,f_deviceLock_EN+sizeof(f_deviceLock_EN))}},
|
||||
{DisType::Dis_Set_ScanNum_Option,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_scannum_EN,f_scannum_EN+sizeof(f_scannum_EN))}},
|
||||
{DisType::Dis_Set_Get_History_ScanNum,{3,1,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_history_num_EN,f_history_num_EN+sizeof(f_history_num_EN))}},
|
||||
{DisType::Dis_Set_Get_Roller_ScanNum,{3,1,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_roller_num_EN,f_roller_num_EN+sizeof(f_roller_num_EN))}},
|
||||
{DisType::Dis_Set_Clear_Roller_ScanNum,{3,40,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_clrea_roller_EN,f_clrea_roller_EN+sizeof(f_clrea_roller_EN))}},
|
||||
{DisType::Dis_Set_Is_Sure,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_is_sure_EN,f_is_sure_EN+sizeof(f_is_sure_EN))}},
|
||||
{DisType::Dis_Set_YES,{3,104,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_yes_EN,f_yes_EN+sizeof(f_yes_EN))}},
|
||||
{DisType::Dis_Set_No,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_no_EN,f_no_EN+sizeof(f_no_EN))}},
|
||||
{DisType::Dis_Language,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_language_EN,f_language_EN+sizeof(f_language_EN))}},
|
||||
{DisType::Dis_Language_Chinese,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_language_chinese,f_language_chinese+sizeof(f_language_chinese))}},
|
||||
{DisType::Dis_Language_Chinese_Traditional,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_language_chinese_traditional,f_language_chinese_traditional+sizeof(f_language_chinese_traditional))}},
|
||||
{DisType::Dis_Language_English,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_language_english,f_language_english+sizeof(f_language_english))}},
|
||||
};
|
||||
|
||||
std::map<DisType,DisInfo> map_Display_TC={
|
||||
{DisType::Dis_Welcome,{1,1,DisDrawtype::DD_All,std::vector<unsigned char>(f_logo,f_logo+sizeof(f_logo))}},
|
||||
{DisType::Dis_Init,{1,1,DisDrawtype::DD_All,std::vector<unsigned char>(f_welcome_TC,f_welcome_TC+sizeof(f_welcome_TC))}},
|
||||
{DisType::Dis_Idel,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_ready_TC,f_ready_TC+sizeof(f_ready_TC))}},
|
||||
{DisType::Dis_Scan,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_scan_TC,f_scan_TC+sizeof(f_scan_TC))}},
|
||||
{DisType::Dis_Set_ClearPaperPass,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_clearpaperpass_TC,f_clearpaperpass_TC+sizeof(f_clearpaperpass_TC))}},
|
||||
{DisType::Dis_Set_Count,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_countmode_TC,f_countmode_TC+sizeof(f_countmode_TC))}},
|
||||
{DisType::Dis_Err_DoubleFeed,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_doublefeed_TC,f_doublefeed_TC+sizeof(f_doublefeed_TC))}},
|
||||
{DisType::Dis_Err_Stable,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_stable_TC,f_stable_TC+sizeof(f_stable_TC))}},
|
||||
{DisType::Dis_Err_CoverOpen,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_coveropen_TC,f_coveropen_TC+sizeof(f_coveropen_TC))}},
|
||||
{DisType::Dis_Err_JamIn,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_paperjam_TC,f_paperjam_TC+sizeof(f_paperjam_TC))}},
|
||||
{DisType::Dis_Err_JamOut,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_paperjam_TC,f_paperjam_TC+sizeof(f_paperjam_TC))}},
|
||||
{DisType::Dis_Err_HandModeJam,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_handmodepaperjam_TC,f_handmodepaperjam_TC+sizeof(f_handmodepaperjam_TC))}},
|
||||
{DisType::Dis_Err_PaperScrew,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_paperscrew_TC,f_paperscrew_TC+sizeof(f_paperscrew_TC))}},
|
||||
{DisType::Dis_Err_FeedError,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_feederror_TC,f_feederror_TC+sizeof(f_feederror_TC))}},
|
||||
{DisType::Dis_Err_AqrImgTimeout,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_aqrimgtimeout_TC,f_aqrimgtimeout_TC+sizeof(f_aqrimgtimeout_TC))}},
|
||||
{DisType::Dis_Err_DogEar,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_dogear_TC,f_dogear_TC+sizeof(f_dogear_TC))}},
|
||||
{DisType::Dis_Err_Size,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_size,f_size+sizeof(f_size))}},
|
||||
{DisType::Dis_Set_PollPaperIntensity,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_pollpaperintensity_TC,f_pollpaperintensity_TC+sizeof(f_pollpaperintensity_TC))}},
|
||||
{DisType::Dis_Set_PollPI_High,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityHigh_TC,f_intensityHigh_TC+sizeof(f_intensityHigh_TC))}},
|
||||
{DisType::Dis_Set_PollPI_Mid,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityMid_TC,f_intensityMid_TC+sizeof(f_intensityMid_TC))}},
|
||||
{DisType::Dis_Set_PollPI_Low,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityLow_TC,f_intensityLow_TC+sizeof(f_intensityLow_TC))}},
|
||||
|
||||
{DisType::Dis_Set_TrayPosition,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_trayposition_TC,f_trayposition_TC+sizeof(f_trayposition_TC))}},
|
||||
{DisType::Dis_Set_TrayPosition_High,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityHigh_TC,f_intensityHigh_TC+sizeof(f_intensityHigh_TC))}},
|
||||
{DisType::Dis_Set_TrayPosition_Mid,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_intensityMid_TC,f_intensityMid_TC+sizeof(f_intensityMid_TC))}},
|
||||
{DisType::Dis_Set_TrayPosition_Low,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_traypositionLow_TC,f_traypositionLow_TC+sizeof(f_traypositionLow_TC))}},
|
||||
|
||||
{DisType::Dis_Count_Page,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_page_TC,f_page_TC+sizeof(f_page_TC))}},
|
||||
{DisType::Dis_Scan_Page,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_page_TC,f_page_TC+sizeof(f_page_TC))}},
|
||||
{DisType::Dis_Err_NoPaper,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_nopaper_TC,f_nopaper_TC+sizeof(f_nopaper_TC))}},
|
||||
{DisType::Dis_Set_SleepMode,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_sleepmode_TC,f_sleepmode_TC+sizeof(f_sleepmode_TC))}},
|
||||
// {DisType::Dis_Set_SleepMode_30M,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_30min,f_30min+sizeof(f_30min))}},
|
||||
// {DisType::Dis_Set_SleepMode_1H,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_1hour,f_1hour+sizeof(f_1hour))}},
|
||||
// {DisType::Dis_Set_SleepMode_2H,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_2hour,f_2hour+sizeof(f_2hour))}},
|
||||
{DisType::Dis_Set_SleepMode_NEVER,{3,80,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_never_TC,f_never_TC+sizeof(f_never_TC))}},
|
||||
{DisType::Dis_Set_Return,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_return_TC,f_return_TC+sizeof(f_return_TC))}},
|
||||
{DisType::Dis_Set_Poweroff,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_powerof_TC,f_powerof_TC+sizeof(f_powerof_TC))}},
|
||||
{DisType::Dis_HandMode,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_handmode_TC,f_handmode_TC+sizeof(f_handmode_TC))}},
|
||||
{DisType::Dis_Set_Item_Return,{3,96,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_return_TC,f_return_TC+sizeof(f_return_TC))}},
|
||||
{DisType::Dis_Device_Lock,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_deviceLock_TC,f_deviceLock_TC+sizeof(f_deviceLock_TC))}},
|
||||
{DisType::Dis_Set_ScanNum_Option,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_scannum_TC,f_scannum_TC+sizeof(f_scannum_TC))}},
|
||||
{DisType::Dis_Set_Get_History_ScanNum,{3,1,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_history_num_TC,f_history_num_TC+sizeof(f_history_num_TC))}},
|
||||
{DisType::Dis_Set_Get_Roller_ScanNum,{3,1,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_roller_num_TC,f_roller_num_TC+sizeof(f_roller_num_TC))}},
|
||||
{DisType::Dis_Set_Clear_Roller_ScanNum,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_clrea_roller_TC,f_clrea_roller_TC+sizeof(f_clrea_roller_TC))}},
|
||||
{DisType::Dis_Set_Is_Sure,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_is_sure_TC,f_is_sure_TC+sizeof(f_is_sure_TC))}},
|
||||
{DisType::Dis_Set_YES,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_yes_TC,f_yes_TC+sizeof(f_yes_TC))}},
|
||||
{DisType::Dis_Set_No,{3,112,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_no_TC,f_no_TC+sizeof(f_no_TC))}},
|
||||
{DisType::Dis_Language,{1,1,DisDrawtype::DD_TopLeft,std::vector<unsigned char>(f_language_TC,f_language_TC+sizeof(f_language_TC))}},
|
||||
{DisType::Dis_Language_Chinese,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_language_chinese,f_language_chinese+sizeof(f_language_chinese))}},
|
||||
{DisType::Dis_Language_Chinese_Traditional,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_language_chinese_traditional,f_language_chinese_traditional+sizeof(f_language_chinese_traditional))}},
|
||||
{DisType::Dis_Language_English,{3,64,DisDrawtype::DD_BotRight,std::vector<unsigned char>(f_language_english,f_language_english+sizeof(f_language_english))}},
|
||||
};
|
||||
};
|
|
@ -0,0 +1,780 @@
|
|||
#include "Lcd.h"
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "DevUtil.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define IOEXPORTPATH "/sys/class/gpio/export"
|
||||
#define DELAY_US(t) this_thread::sleep_for(chrono::microseconds((t)))
|
||||
#define DELAY_MS(t) this_thread::sleep_for(chrono::milliseconds((t)))
|
||||
|
||||
static unsigned char ascii_table_8x16[95][16] = {
|
||||
|
||||
/*-- 文字: --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: ! --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: " --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: # --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00,
|
||||
|
||||
/*-- 文字: $ --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: % --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00,
|
||||
|
||||
/*-- 文字: & --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10,
|
||||
|
||||
/*-- 文字: ' --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: ( --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00,
|
||||
|
||||
/*-- 文字: ) --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: * --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00,
|
||||
|
||||
/*-- 文字: + --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00,
|
||||
|
||||
/*-- 文字: , --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: - --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
|
||||
/*-- 文字: . --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: / --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: 0 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00,
|
||||
|
||||
/*-- 文字: 1 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: 2 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00,
|
||||
|
||||
/*-- 文字: 3 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00,
|
||||
|
||||
/*-- 文字: 4 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00,
|
||||
|
||||
/*-- 文字: 5 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00,
|
||||
|
||||
/*-- 文字: 6 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00,
|
||||
|
||||
/*-- 文字: 7 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: 8 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00,
|
||||
|
||||
/*-- 文字: 9 --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00,
|
||||
|
||||
/*-- 文字: : --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: ; --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: < --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
|
||||
|
||||
/*-- 文字: = --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00,
|
||||
|
||||
/*-- 文字: > --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00,
|
||||
|
||||
/*-- 文字: ? --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: @ --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00,
|
||||
|
||||
/*-- 文字: A --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20,
|
||||
|
||||
/*-- 文字: B --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00,
|
||||
|
||||
/*-- 文字: C --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00,
|
||||
|
||||
/*-- 文字: D --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00,
|
||||
|
||||
/*-- 文字: E --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00,
|
||||
|
||||
/*-- 文字: F --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: G --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00,
|
||||
|
||||
/*-- 文字: H --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20,
|
||||
|
||||
/*-- 文字: I --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: J --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: K --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00,
|
||||
|
||||
/*-- 文字: L --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00,
|
||||
|
||||
/*-- 文字: M --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00,
|
||||
|
||||
/*-- 文字: N --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00,
|
||||
|
||||
/*-- 文字: O --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00,
|
||||
|
||||
/*-- 文字: P --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: Q --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00,
|
||||
|
||||
/*-- 文字: R --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20,
|
||||
|
||||
/*-- 文字: S --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00,
|
||||
|
||||
/*-- 文字: T --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: U --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00,
|
||||
|
||||
/*-- 文字: V --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: W --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00,
|
||||
|
||||
/*-- 文字: X --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20,
|
||||
|
||||
/*-- 文字: Y --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: Z --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00,
|
||||
|
||||
/*-- 文字: [ --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00,
|
||||
|
||||
/*-- 文字: \ --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00,
|
||||
|
||||
/*-- 文字: ] --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: ^ --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: _ --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
|
||||
/*-- 文字: ` --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: a --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20,
|
||||
|
||||
/*-- 文字: b --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00,
|
||||
|
||||
/*-- 文字: c --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00,
|
||||
|
||||
/*-- 文字: d --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20,
|
||||
|
||||
/*-- 文字: e --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00,
|
||||
|
||||
/*-- 文字: f --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: g --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00,
|
||||
|
||||
/*-- 文字: h --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20,
|
||||
|
||||
/*-- 文字: i --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: j --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: k --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00,
|
||||
|
||||
/*-- 文字: l --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: m --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F,
|
||||
|
||||
/*-- 文字: n --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20,
|
||||
|
||||
/*-- 文字: o --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00,
|
||||
|
||||
/*-- 文字: p --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00,
|
||||
|
||||
/*-- 文字: q --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80,
|
||||
|
||||
/*-- 文字: r --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00,
|
||||
|
||||
/*-- 文字: s --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00,
|
||||
|
||||
/*-- 文字: t --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: u --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20,
|
||||
|
||||
/*-- 文字: v --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00,
|
||||
|
||||
/*-- 文字: w --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00,
|
||||
|
||||
/*-- 文字: x --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00,
|
||||
|
||||
/*-- 文字: y --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00,
|
||||
|
||||
/*-- 文字: z --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00,
|
||||
|
||||
/*-- 文字: { --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40,
|
||||
|
||||
/*-- 文字: | --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: } --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/*-- 文字: ~ --*/
|
||||
/*-- Comic Sans MS12; 此字体下对应的点阵为:宽x高=8x16 --*/
|
||||
0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
};
|
||||
|
||||
static unsigned char ascii_table_5x8[95][5] = {
|
||||
/*全体ASCII 列表:5x8点阵*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, //space
|
||||
0x00, 0x00, 0x4f, 0x00, 0x00, //!
|
||||
0x00, 0x07, 0x00, 0x07, 0x00, //"
|
||||
0x14, 0x7f, 0x14, 0x7f, 0x14, //#
|
||||
0x24, 0x2a, 0x7f, 0x2a, 0x12, //$
|
||||
0x23, 0x13, 0x08, 0x64, 0x62, //%
|
||||
0x36, 0x49, 0x55, 0x22, 0x50, //&
|
||||
0x00, 0x05, 0x07, 0x00, 0x00, //]
|
||||
0x00, 0x1c, 0x22, 0x41, 0x00, //(
|
||||
0x00, 0x41, 0x22, 0x1c, 0x00, //)
|
||||
0x14, 0x08, 0x3e, 0x08, 0x14, //*
|
||||
0x08, 0x08, 0x3e, 0x08, 0x08, //+
|
||||
0x00, 0x50, 0x30, 0x00, 0x00, //,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, //-
|
||||
0x00, 0x60, 0x60, 0x00, 0x00, //.
|
||||
0x20, 0x10, 0x08, 0x04, 0x02, ///
|
||||
0x3e, 0x51, 0x49, 0x45, 0x3e, //0
|
||||
0x00, 0x42, 0x7f, 0x40, 0x00, //1
|
||||
0x42, 0x61, 0x51, 0x49, 0x46, //2
|
||||
0x21, 0x41, 0x45, 0x4b, 0x31, //3
|
||||
0x18, 0x14, 0x12, 0x7f, 0x10, //4
|
||||
0x27, 0x45, 0x45, 0x45, 0x39, //5
|
||||
0x3c, 0x4a, 0x49, 0x49, 0x30, //6
|
||||
0x01, 0x71, 0x09, 0x05, 0x03, //7
|
||||
0x36, 0x49, 0x49, 0x49, 0x36, //8
|
||||
0x06, 0x49, 0x49, 0x29, 0x1e, //9
|
||||
0x00, 0x36, 0x36, 0x00, 0x00, //:
|
||||
0x00, 0x56, 0x36, 0x00, 0x00, //;
|
||||
0x08, 0x14, 0x22, 0x41, 0x00, //<
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, //=
|
||||
0x00, 0x41, 0x22, 0x14, 0x08, //>
|
||||
0x02, 0x01, 0x51, 0x09, 0x06, //?
|
||||
0x32, 0x49, 0x79, 0x41, 0x3e, //@
|
||||
0x7e, 0x11, 0x11, 0x11, 0x7e, //A
|
||||
0x7f, 0x49, 0x49, 0x49, 0x36, //B
|
||||
0x3e, 0x41, 0x41, 0x41, 0x22, //C
|
||||
0x7f, 0x41, 0x41, 0x22, 0x1c, //D
|
||||
0x7f, 0x49, 0x49, 0x49, 0x41, //E
|
||||
0x7f, 0x09, 0x09, 0x09, 0x01, //F
|
||||
0x3e, 0x41, 0x49, 0x49, 0x7a, //G
|
||||
0x7f, 0x08, 0x08, 0x08, 0x7f, //H
|
||||
0x00, 0x41, 0x7f, 0x41, 0x00, //I
|
||||
0x20, 0x40, 0x41, 0x3f, 0x01, //J
|
||||
0x7f, 0x08, 0x14, 0x22, 0x41, //K
|
||||
0x7f, 0x40, 0x40, 0x40, 0x40, //L
|
||||
0x7f, 0x02, 0x0c, 0x02, 0x7f, //M
|
||||
0x7f, 0x04, 0x08, 0x10, 0x7f, //N
|
||||
0x3e, 0x41, 0x41, 0x41, 0x3e, //O
|
||||
0x7f, 0x09, 0x09, 0x09, 0x06, //P
|
||||
0x3e, 0x41, 0x51, 0x21, 0x5e, //Q
|
||||
0x7f, 0x09, 0x19, 0x29, 0x46, //R
|
||||
0x46, 0x49, 0x49, 0x49, 0x31, //S
|
||||
0x01, 0x01, 0x7f, 0x01, 0x01, //T
|
||||
0x3f, 0x40, 0x40, 0x40, 0x3f, //U
|
||||
0x1f, 0x20, 0x40, 0x20, 0x1f, //V
|
||||
0x3f, 0x40, 0x38, 0x40, 0x3f, //W
|
||||
0x63, 0x14, 0x08, 0x14, 0x63, //X
|
||||
0x07, 0x08, 0x70, 0x08, 0x07, //Y
|
||||
0x61, 0x51, 0x49, 0x45, 0x43, //Z
|
||||
0x00, 0x7f, 0x41, 0x41, 0x00, //[
|
||||
0x02, 0x04, 0x08, 0x10, 0x20, //\
|
||||
0x00,0x41,0x41,0x7f,0x00,//]
|
||||
0x04, 0x02, 0x01, 0x02, 0x04, //^
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, //_
|
||||
0x01, 0x02, 0x04, 0x00, 0x00, //`
|
||||
0x20, 0x54, 0x54, 0x54, 0x78, //a
|
||||
0x7f, 0x48, 0x48, 0x48, 0x30, //b
|
||||
0x38, 0x44, 0x44, 0x44, 0x44, //c
|
||||
0x30, 0x48, 0x48, 0x48, 0x7f, //d
|
||||
0x38, 0x54, 0x54, 0x54, 0x58, //e
|
||||
0x00, 0x08, 0x7e, 0x09, 0x02, //f
|
||||
0x48, 0x54, 0x54, 0x54, 0x3c, //g
|
||||
0x7f, 0x08, 0x08, 0x08, 0x70, //h
|
||||
0x00, 0x00, 0x7a, 0x00, 0x00, //i
|
||||
0x20, 0x40, 0x40, 0x3d, 0x00, //j
|
||||
0x7f, 0x20, 0x28, 0x44, 0x00, //k
|
||||
0x00, 0x41, 0x7f, 0x40, 0x00, //l
|
||||
0x7c, 0x04, 0x38, 0x04, 0x7c, //m
|
||||
0x7c, 0x08, 0x04, 0x04, 0x78, //n
|
||||
0x38, 0x44, 0x44, 0x44, 0x38, //o
|
||||
0x7c, 0x14, 0x14, 0x14, 0x08, //p
|
||||
0x08, 0x14, 0x14, 0x14, 0x7c, //q
|
||||
0x7c, 0x08, 0x04, 0x04, 0x08, //r
|
||||
0x48, 0x54, 0x54, 0x54, 0x24, //s
|
||||
0x04, 0x04, 0x3f, 0x44, 0x24, //t
|
||||
0x3c, 0x40, 0x40, 0x40, 0x3c, //u
|
||||
0x1c, 0x20, 0x40, 0x20, 0x1c, //v
|
||||
0x3c, 0x40, 0x30, 0x40, 0x3c, //w
|
||||
0x44, 0x28, 0x10, 0x28, 0x44, //x
|
||||
0x04, 0x48, 0x30, 0x08, 0x04, //y
|
||||
0x44, 0x64, 0x54, 0x4c, 0x44, //z
|
||||
0x08, 0x36, 0x41, 0x41, 0x00, //{
|
||||
0x00, 0x00, 0x77, 0x00, 0x00, //|
|
||||
0x00, 0x41, 0x41, 0x36, 0x08, //}
|
||||
0x04, 0x02, 0x02, 0x02, 0x01, //~
|
||||
};
|
||||
|
||||
|
||||
Lcd::Lcd() : spi_sck(51), spi_sda(72), spi_cs(154), spi_reset(150), spi_rs(156),COM_BOOT0(153)
|
||||
|
||||
{
|
||||
printf("Lcd()\n");
|
||||
write_dev(IOEXPORTPATH,51);
|
||||
write_dev(IOEXPORTPATH,72);
|
||||
write_dev(IOEXPORTPATH,154);
|
||||
write_dev(IOEXPORTPATH,150);
|
||||
write_dev(IOEXPORTPATH,156);
|
||||
write_dev(IOEXPORTPATH,153);
|
||||
|
||||
COM_BOOT0.setDirection(Gpio::out);
|
||||
spi_sck.setDirection(Gpio::out);
|
||||
spi_sda.setDirection(Gpio::out);
|
||||
spi_cs.setDirection(Gpio::out);
|
||||
spi_reset.setDirection(Gpio::out);
|
||||
spi_rs.setDirection(Gpio::out);
|
||||
|
||||
COM_BOOT0.setValue(Gpio::Low);
|
||||
spi_sck.setValue(Gpio::High);
|
||||
spi_sda.setValue(Gpio::High);
|
||||
spi_cs.setValue(Gpio::High);
|
||||
spi_reset.setValue(Gpio::High);
|
||||
spi_rs.setValue(Gpio::High);
|
||||
}
|
||||
|
||||
/*=======写指令========*/
|
||||
void Lcd::Lcd_Transfer_Command(int data1)
|
||||
{
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
spi_rs.setValue(Gpio::Low);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
spi_sck.setValue(Gpio::Low);
|
||||
|
||||
if (data1 & 0x80)
|
||||
spi_sda.setValue(Gpio::High);
|
||||
else
|
||||
spi_sda.setValue(Gpio::Low);
|
||||
spi_sck.setValue(Gpio::High);
|
||||
data1 = data1 <<= 1;
|
||||
}
|
||||
spi_cs.setValue(Gpio::High);
|
||||
}
|
||||
|
||||
/*--------写数据------------*/
|
||||
void Lcd::Lcd_Transfer_data(int data1)
|
||||
{
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
spi_rs.setValue(Gpio::High);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
spi_sck.setValue(Gpio::Low);
|
||||
if (data1 & 0x80)
|
||||
spi_sda.setValue(Gpio::High);
|
||||
else
|
||||
spi_sda.setValue(Gpio::Low);
|
||||
spi_sck.setValue(Gpio::High);
|
||||
data1 = data1 <<= 1;
|
||||
}
|
||||
spi_cs.setValue(Gpio::High);
|
||||
}
|
||||
|
||||
/*LCD模块初始化*/
|
||||
void Lcd::Lcd_Initial_Lcd(bool biglcd)
|
||||
{
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
spi_reset.setValue(Gpio::Low); /*低电平复位*/
|
||||
DELAY_MS(20);
|
||||
spi_reset.setValue(Gpio::High); /*复位完毕*/
|
||||
DELAY_MS(20);
|
||||
Lcd_Transfer_Command(0xe2); /*软复位*/
|
||||
DELAY_MS(50);
|
||||
Lcd_Transfer_Command(0x2c); /*升压步聚1*/
|
||||
DELAY_MS(50);
|
||||
Lcd_Transfer_Command(0x2e); /*升压步聚2*/
|
||||
DELAY_MS(50);
|
||||
Lcd_Transfer_Command(0x2f); /*升压步聚3*/
|
||||
DELAY_MS(50);
|
||||
Lcd_Transfer_Command(biglcd?0x21:0x24); /*0X24粗调对比度,可设置范围0x20~0x27*/
|
||||
Lcd_Transfer_Command(0x81); /*微调对比度*/
|
||||
Lcd_Transfer_Command(biglcd?0x28:0x15); /*45微调对比度的值,可设置范围0x00~0x3f 1f*/ // 0~63
|
||||
Lcd_Transfer_Command(0xa2); /*1/9偏压比(bias)0xa2 ,1/7bias 0xa3*/
|
||||
Lcd_Transfer_Command(0xc8); /*行扫描顺序:从上到下*/ //原 c0 字体倒置 CF /////////////////////////////////////////////////////////////
|
||||
Lcd_Transfer_Command(0xa0); /*列扫描顺序:从左到右*/ //原 a1 字体倒置 A0 ////////////////////////////////////////////////
|
||||
Lcd_Transfer_Command(0x40); /*起始行:第一行开始*/
|
||||
Lcd_Transfer_Command(0xaf); /*开显示*/
|
||||
spi_cs.setValue(Gpio::High);
|
||||
}
|
||||
|
||||
void Lcd::Lcd_Address(unsigned char page, unsigned char column)
|
||||
{
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
column = column - 1;
|
||||
page = page - 1;
|
||||
Lcd_Transfer_Command(0xb0 + page); //设置页地址。每页是8行。一个画面的64行被分成8个页。我们平常所说的第1页,在LCD驱动IC里是第0页,所以在这里减去1*/
|
||||
Lcd_Transfer_Command(((column >> 4) & 0x0f) + 0x10); //设置列地址的高4位
|
||||
Lcd_Transfer_Command(column & 0x0f); //设置列地址的低4位
|
||||
}
|
||||
|
||||
/*全屏清屏*/
|
||||
void Lcd::Lcd_Clear_screen()
|
||||
{
|
||||
unsigned char i, j;
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
Lcd_Address(1 + i, 1);
|
||||
for (j = 0; j < 132; j++)
|
||||
{
|
||||
Lcd_Transfer_data(0x00);
|
||||
}
|
||||
}
|
||||
spi_cs.setValue(Gpio::High);
|
||||
}
|
||||
|
||||
//===显示测试画面:例如全显示,隔行显示,隔列显示,雪花显示=====
|
||||
void Lcd::Lcd_Test_Display(unsigned char data1, unsigned char data2)
|
||||
{
|
||||
int i, j;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
Lcd_Address(j + 1, 1);
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
Lcd_Transfer_data(data1);
|
||||
Lcd_Transfer_data(data2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*显示128x64点阵图像*/
|
||||
void Lcd::Lcd_Display_Graphic_128x64(unsigned char page, unsigned char column, unsigned char *dp)
|
||||
{
|
||||
int i, j;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
Lcd_Address(page + j, column);
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
Lcd_Transfer_data(*dp);
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*显示32x32点阵图像、汉字、生僻字或32x32点阵的其他图标*/
|
||||
void Lcd::Lcd_Display_graphic_32x32(unsigned char page, unsigned char column, unsigned char *dp)
|
||||
{
|
||||
unsigned char i, j;
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
Lcd_Address(page + j, column);
|
||||
for (i = 0; i < 31; i++)
|
||||
{
|
||||
Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/
|
||||
void Lcd::Lcd_Display_Graphic_16x16_2(unsigned char reverse, unsigned char page, unsigned char column, unsigned char *dp)
|
||||
{
|
||||
unsigned char i, j;
|
||||
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
Lcd_Address(page + j, column);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (reverse == 1)
|
||||
Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
|
||||
else
|
||||
Lcd_Transfer_data(~*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
spi_cs.setValue(Gpio::High);
|
||||
}
|
||||
|
||||
/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/
|
||||
void Lcd::Lcd_Display_Graphic_16x16(unsigned char page, unsigned char column, unsigned char *dp, unsigned int wordcount)
|
||||
{
|
||||
unsigned char i, j, k;
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
for (k = 0; k < wordcount; k++)
|
||||
{
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
Lcd_Address(page + j, column + 16 * k);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
spi_cs.setValue(Gpio::High);
|
||||
}
|
||||
|
||||
/*显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标*/
|
||||
void Lcd::Lcd_Display_Graphic_8x16(unsigned char page, unsigned char column, unsigned char *dp)
|
||||
{
|
||||
unsigned char i, j;
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
Lcd_Address(page + j, column);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
Lcd_Transfer_data(*dp); /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
spi_cs.setValue(Gpio::High);
|
||||
}
|
||||
|
||||
void Lcd::Lcd_Display_String_8x16(unsigned int page, unsigned int column, const char *text)
|
||||
{
|
||||
unsigned int i = 0, j, k, n;
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
while (text[i] > 0x00)
|
||||
{
|
||||
if ((text[i] >= 0x20) && (text[i] <= 0x7e))
|
||||
{
|
||||
j = text[i] - 0x20;
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
Lcd_Address(page + n, column);
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
Lcd_Transfer_data(ascii_table_8x16[j][k + 8 * n]); /*显示5x7的ASCII字到LCD上,y为页地址,x为列地址,最后为数据*/
|
||||
}
|
||||
}
|
||||
i++;
|
||||
column += 8;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void Lcd::Lcd_Display_String_5x8(unsigned int page, unsigned int column, const char *text)
|
||||
{
|
||||
unsigned int i = 0, j, k;
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
while (text[i] > 0x00)
|
||||
{
|
||||
if ((text[i] >= 0x20) && (text[i] < 0x7e))
|
||||
{
|
||||
j = text[i] - 0x20;
|
||||
Lcd_Address(page, column);
|
||||
for (k = 0; k < 5; k++)
|
||||
{
|
||||
Lcd_Transfer_data(ascii_table_5x8[j][k]); /*显示5x7的ASCII字到LCD上,y为页地址,x为列地址,最后为数据*/
|
||||
}
|
||||
i++;
|
||||
column += 6;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void Lcd::Lcd_Clear_Half_Screen(bool top)
|
||||
{
|
||||
int pageindex = top ? 0 : 2;
|
||||
int pagemaxindex = top ? 2 : 4;
|
||||
spi_cs.setValue(Gpio::Low);
|
||||
for (int i = pageindex; i < pagemaxindex; i++)
|
||||
{
|
||||
Lcd_Address(1 + i, 1);
|
||||
for (int j = 0; j < 132; j++)
|
||||
{
|
||||
Lcd_Transfer_data(0x00);
|
||||
}
|
||||
}
|
||||
spi_cs.setValue(Gpio::High);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sstream>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "Gpio.h"
|
||||
|
||||
class Lcd
|
||||
{
|
||||
private:
|
||||
Gpio spi_sck;
|
||||
Gpio spi_sda;
|
||||
Gpio spi_cs;
|
||||
Gpio spi_reset;
|
||||
Gpio spi_rs;
|
||||
Gpio COM_BOOT0;
|
||||
|
||||
public:
|
||||
Lcd();
|
||||
/*=======写指令========*/
|
||||
void Lcd_Transfer_Command(int data1);
|
||||
|
||||
/*--------写数据------------*/
|
||||
void Lcd_Transfer_data(int data1);
|
||||
|
||||
/*LCD模块初始化*/
|
||||
void Lcd_Initial_Lcd(bool biglcd);
|
||||
|
||||
void Lcd_Address(unsigned char page, unsigned char column);
|
||||
|
||||
/*全屏清屏*/
|
||||
void Lcd_Clear_screen();
|
||||
|
||||
void Lcd_Clear_Half_Screen(bool top);
|
||||
|
||||
//===显示测试画面:例如全显示,隔行显示,隔列显示,雪花显示=====
|
||||
void Lcd_Test_Display(unsigned char data1, unsigned char data2);
|
||||
|
||||
/*显示128x64点阵图像*/
|
||||
void Lcd_Display_Graphic_128x64(unsigned char page, unsigned char column, unsigned char *dp);
|
||||
|
||||
/*显示32x32点阵图像、汉字、生僻字或32x32点阵的其他图标*/
|
||||
void Lcd_Display_graphic_32x32(unsigned char page, unsigned char column, unsigned char *dp);
|
||||
|
||||
/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/
|
||||
void Lcd_Display_Graphic_16x16_2(unsigned char reverse,unsigned char page,unsigned char column,unsigned char *dp);
|
||||
|
||||
/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/
|
||||
void Lcd_Display_Graphic_16x16(unsigned char page, unsigned char column, unsigned char *dp,unsigned int wordcount);
|
||||
|
||||
/*显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标*/
|
||||
void Lcd_Display_Graphic_8x16(unsigned char page, unsigned char column,unsigned char *dp);
|
||||
|
||||
void Lcd_Display_String_8x16(unsigned int page, unsigned int column, const char *text);
|
||||
|
||||
void Lcd_Display_String_5x8(unsigned int page, unsigned int column, const char *text);
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
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,121 @@
|
|||
#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,23 @@
|
|||
#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,358 @@
|
|||
/*
|
||||
* 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,247 @@
|
|||
/*
|
||||
* 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,110 @@
|
|||
/*
|
||||
* 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,404 @@
|
|||
/*
|
||||
* 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,100 @@
|
|||
/*
|
||||
* 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__ */
|
|
@ -0,0 +1,6 @@
|
|||
ch455_key:ch455_key.cpp
|
||||
g++ $^ -o $@
|
||||
|
||||
clean:
|
||||
rm ch455_key
|
||||
|
Binary file not shown.
|
@ -0,0 +1,330 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define I2C_SDA 43 // GPIO1_B3
|
||||
#define I2C_SCL 44 // GPIO1_B4
|
||||
#define I2C_INT 52
|
||||
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned short UINT16;
|
||||
|
||||
#define STATUS_SUCCESS 0
|
||||
#define STATUS_FAILURE -1
|
||||
|
||||
#define CH455_GET_KEY 0x0700 // 获取按键,返回按键代码
|
||||
#define CH455_SYSOFF 0x0400 // 关闭显示、关闭键盘
|
||||
|
||||
#define CH455_I2C_ADDR 0x40 // CH455的地址
|
||||
#define CH455_I2C_MASK 0x3E // CH455的高字节命令掩码
|
||||
|
||||
#define CH455_BIT_ENABLE 0x01
|
||||
// #define CH455_BIT_ENABLE 0x03 // 开启/关闭位
|
||||
#define CH455_BIT_SLEEP 0x04 // 睡眠控制位
|
||||
|
||||
#define CH455_SYSON (CH455_SYSOFF | CH455_BIT_ENABLE)
|
||||
#define CH455_SLEEPOFF CH455_SYSOFF // 关闭睡眠
|
||||
#define CH455_SLEEPON (CH455_SYSOFF | CH455_BIT_SLEEP) // 开启睡眠
|
||||
|
||||
static unsigned char TxBuf[24] = {0};
|
||||
static unsigned char RxBuf[24] = {0};
|
||||
|
||||
void CH455_I2c_Stop(void);
|
||||
void CH455_I2C_WrByte(unsigned char IIC_Byte);
|
||||
|
||||
void delay_us(int i)
|
||||
{
|
||||
int j, k;
|
||||
for (j = 0; j < i; j++)
|
||||
for (k = 0; k < 10; k++)
|
||||
;
|
||||
}
|
||||
|
||||
void initGpio(int addr)
|
||||
{
|
||||
// printf("开始创建GPIO%d节点\n", addr);
|
||||
FILE *fp = fopen("/sys/class/gpio/export", "w");
|
||||
if (fp == NULL)
|
||||
perror("export open filed");
|
||||
else
|
||||
fprintf(fp, "%d", addr);
|
||||
|
||||
fclose(fp);
|
||||
// printf("结束创建GPIO%d节点\n", addr);
|
||||
}
|
||||
|
||||
// 设置为gpio方向
|
||||
void setGpioDirection(int addr, char *direction)
|
||||
{
|
||||
// printf("设置第GPIO%d为out模式\n",addr);
|
||||
char path[100] = {0};
|
||||
sprintf(path, "/sys/class/gpio/gpio%d/direction", addr);
|
||||
FILE *fp = fopen(path, "w");
|
||||
if (fp == NULL)
|
||||
perror("direction open filed");
|
||||
else
|
||||
fprintf(fp, "%s", direction);
|
||||
fclose(fp);
|
||||
// printf("结束设置第GPIO%d为out模式\n",addr);
|
||||
}
|
||||
|
||||
// 设置gpio的电平
|
||||
void set_gpioValue(int addr, int value)
|
||||
{
|
||||
// printf("设置GPIO%d为%d\n", addr, value);
|
||||
char path[64];
|
||||
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", addr);
|
||||
FILE *fp = fopen(path, "w");
|
||||
if (fp == NULL)
|
||||
perror("direction open filed");
|
||||
else
|
||||
fprintf(fp, "%d", value);
|
||||
fclose(fp);
|
||||
// printf("结束设置GPIO%d位置为%d\n", addr, value);
|
||||
}
|
||||
|
||||
void IOWR_OUT(int addr, int val)
|
||||
{
|
||||
initGpio(addr);
|
||||
setGpioDirection(addr, "out");
|
||||
set_gpioValue(addr, val);
|
||||
}
|
||||
|
||||
void IOWR_IN(int addr, int val)
|
||||
{
|
||||
initGpio(addr);
|
||||
setGpioDirection(addr, "in");
|
||||
set_gpioValue(addr, val);
|
||||
}
|
||||
|
||||
// 读gpio节点状态
|
||||
int IORD(int addr)
|
||||
{
|
||||
char path[64];
|
||||
char value_str[3];
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", addr);
|
||||
// printf("/sys/class/gpio/gpio%d/value", addr);
|
||||
FILE *fp = fopen(path, "r");
|
||||
|
||||
// fd = open(path, O_RDONLY);
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("Failed to open gpio value for reading!");
|
||||
return -1;
|
||||
}
|
||||
if (fread(value_str, sizeof(char), 3, fp) < 0)
|
||||
{
|
||||
perror("Failed to read value!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
// printf("读取GPIO状态结束\n");
|
||||
return (atoi(value_str));
|
||||
}
|
||||
|
||||
// 开始位
|
||||
void CH455_I2c_Start(void)
|
||||
{
|
||||
IOWR_OUT(I2C_SDA, 1);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 1);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SDA, 0);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 0);
|
||||
delay_us(5);
|
||||
}
|
||||
|
||||
// 结束位
|
||||
void CH455_I2c_Stop(void)
|
||||
{
|
||||
IOWR_OUT(I2C_SCL, 0);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SDA, 0);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 1);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SDA, 1);
|
||||
delay_us(5);
|
||||
}
|
||||
|
||||
// 主控端写入一个字节到从机
|
||||
void CH455_I2C_WrByte(unsigned char IIC_Byte)
|
||||
{
|
||||
unsigned char i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
// IOWR(I2C_SCL, 0); //钳住I2C总线,准备发送数据
|
||||
if (IIC_Byte & 0x80)
|
||||
IOWR_OUT(I2C_SDA, 1);
|
||||
else
|
||||
IOWR_OUT(I2C_SDA, 0);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 1);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 0);
|
||||
delay_us(5);
|
||||
IIC_Byte <<= 1;
|
||||
}
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SDA, 1);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 1);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 0);
|
||||
delay_us(5);
|
||||
}
|
||||
|
||||
// 主控端对从机读取一个字节
|
||||
static unsigned char CH455_I2C_RdByte(void) // 读取一个字节数据
|
||||
{
|
||||
unsigned char i = 0;
|
||||
unsigned char bytedata = 0;
|
||||
delay_us(5);
|
||||
// 将数据设置为输入模式
|
||||
IOWR_IN(I2C_SDA, 1);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 0);
|
||||
delay_us(5);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
IOWR_OUT(I2C_SCL, 1);
|
||||
delay_us(5);
|
||||
bytedata <<= 1;
|
||||
delay_us(5);
|
||||
bytedata = bytedata | (IORD(I2C_SDA));
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 0);
|
||||
delay_us(5);
|
||||
}
|
||||
IOWR_OUT(I2C_SDA, 1); // 数据线设置回输出模式
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 1);
|
||||
delay_us(5);
|
||||
IOWR_OUT(I2C_SCL, 0);
|
||||
delay_us(5);
|
||||
return (bytedata); // 返回数据
|
||||
}
|
||||
|
||||
// 写命令
|
||||
static unsigned char CH455_Write(UINT16 cmd)
|
||||
{
|
||||
printf("CH455_Write start...\n");
|
||||
CH455_I2c_Start(); // 启动总线
|
||||
printf("CH455_Write first byte= %02x\n", ((UINT8)(cmd >> 7) & CH455_I2C_MASK) | CH455_I2C_ADDR);
|
||||
printf("CH455_Write second byte= %02x\n", (UINT8)cmd);
|
||||
CH455_I2C_WrByte(((UINT8)(cmd >> 7) & CH455_I2C_MASK) | CH455_I2C_ADDR);
|
||||
CH455_I2C_WrByte((UINT8)cmd); // 发送数据
|
||||
CH455_I2c_Stop(); // 结束总线
|
||||
printf("CH455_Write end...\n");
|
||||
printf("\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned char CH455_Read(void) // 读取按键值
|
||||
{
|
||||
printf("CH455_Read start...\n");
|
||||
UINT8 keycode;
|
||||
CH455_I2c_Start(); // 启动总线
|
||||
printf("write byte= %02x\n", (UINT8)(CH455_GET_KEY >> 7) & CH455_I2C_MASK | 0x01 | CH455_I2C_ADDR);
|
||||
CH455_I2C_WrByte((UINT8)(CH455_GET_KEY >> 7) & CH455_I2C_MASK | 0x01 | CH455_I2C_ADDR);
|
||||
keycode = CH455_I2C_RdByte(); // 读取数据
|
||||
printf("read byte= %02x\n", keycode);
|
||||
CH455_I2c_Stop(); // 结束总线
|
||||
printf("CH455_Read end...\n");
|
||||
printf("\n");
|
||||
return keycode;
|
||||
}
|
||||
|
||||
void key_Inter(void)
|
||||
{
|
||||
int ret;
|
||||
int val = 0;
|
||||
char buf[8];
|
||||
int num;
|
||||
UINT16 key_value;
|
||||
pollfd pfd;
|
||||
pfd.fd = -1;
|
||||
pfd.fd = open("/sys/class/gpio/gpio52/value", O_RDONLY);
|
||||
if (pfd.fd > 0)
|
||||
printf("huagao::open sucess,fd = %d\n", pfd.fd);
|
||||
else
|
||||
printf("huagao::open failed,fd = %d\n", pfd.fd);
|
||||
pfd.events = POLLPRI;
|
||||
num = read(pfd.fd, buf, 8); // This is to clear the avaible read
|
||||
for (int i = 0; i < 8; i++)
|
||||
printf("huagao::buf[%d] = %d\n", i, buf[i]);
|
||||
|
||||
ret = CH455_Write(CH455_SYSON);
|
||||
printf("CH455_SYSON = %02x\n", (CH455_SYSON));
|
||||
printf("CH455_Read() = %02x\n", CH455_Read());
|
||||
key_value = 0xff;
|
||||
while (1)
|
||||
{
|
||||
ret = poll(&pfd, 1, 1000);
|
||||
if (ret > 0)
|
||||
{
|
||||
printf("--------------------------------------------\n");
|
||||
printf("huagao::poll get date.\n");
|
||||
printf("huagao::poll ret = %d\n", ret);
|
||||
/*
|
||||
POLLIN: 有普通数据或者优先数据可读
|
||||
POLLRDNORM: 有普通数据可读
|
||||
POLLRDBAND: 有优先数据可读
|
||||
POLLPRI: 有紧急数据可读
|
||||
POLLOUT: 有普通数据可写
|
||||
POLLWRNORM: 有普通数据可写
|
||||
POLLWRBAND: 有紧急数据可写
|
||||
POLLERR: 有错误发生
|
||||
POLLHUP: 有描述符挂起事件发生
|
||||
POLLNVAL: 描述符非法
|
||||
*/
|
||||
if (pfd.revents & POLLPRI)
|
||||
{
|
||||
lseek(pfd.fd, 0, SEEK_SET);
|
||||
num = read(pfd.fd, buf, 8);
|
||||
buf[num - 1] = '\0';
|
||||
ret = atoi(buf);
|
||||
for (int i = 0; i < 8; i++)
|
||||
printf("huagao::buf[%d] = %d\n", i, buf[i]);
|
||||
printf("huagao::atoi(buf) ret = %d\n", ret);
|
||||
}
|
||||
key_value = CH455_Read();
|
||||
printf("CH455_Read() = %02x\n", key_value);
|
||||
printf("--------------------------------------------\n");
|
||||
printf("\n");
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
printf("--------------------------------------------\n");
|
||||
printf("huagao::ret = %d\n", ret);
|
||||
printf("huagao::poll time out.\n");
|
||||
printf("--------------------------------------------\n");
|
||||
printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("--------------------------------------------\n");
|
||||
printf("huagao::ret = %d\n", ret);
|
||||
printf("huagao::poll err.\n");
|
||||
printf("--------------------------------------------\n");
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
system("echo 52 > /sys/class/gpio/export");
|
||||
system("echo in > /sys/class/gpio/gpio52/direction");
|
||||
system("echo falling > /sys/class/gpio/gpio52/edge");
|
||||
key_Inter();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
project(imgproc)
|
||||
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)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/imageprocess DIR_SUBSRC)
|
||||
file(GLOB DIR_HEADS "${PROJECT_SOURCE_DIR}/*.h" "${PROJECT_SOURCE_DIR}/*.hpp")
|
||||
set(DIR_SRCS ${DIR_SRCS} ${DIR_HEADS})
|
||||
|
||||
if(CMAKE_HOST_WIN32)
|
||||
link_libraries(
|
||||
libopencv_world.a
|
||||
liblibjasper.a
|
||||
libittnotify.a
|
||||
libtegra_hal.a
|
||||
libzlib.a
|
||||
liblibjpeg-turbo.a
|
||||
liblibpng.a
|
||||
liblibtiff.a
|
||||
liblibwebp.a
|
||||
)
|
||||
endif()
|
||||
add_library(${PROJECT_NAME} STATIC ${DIR_SRCS} ${DIR_SUBSRC})
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_SOURCE_DIR}/imageprocess
|
||||
${PROJECT_SOURCE_DIR}/../packages/common.pkg/include
|
||||
|
||||
)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
|
|
@ -0,0 +1,285 @@
|
|||
#include "CSizedetect.h"
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "ImageProcess_Public.h"
|
||||
#include "commondef.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) : m_papertype(papaertype),
|
||||
m_horThre(70),
|
||||
m_verThre(100)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
printf("\n width =%f ,height = %f ", width, 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 ((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 "commondef.h"
|
||||
|
||||
class CSizedetect : public IPreproc
|
||||
{
|
||||
public:
|
||||
explicit CSizedetect(int papaertype);
|
||||
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;
|
||||
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, 3400}},
|
||||
{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, 8189}}};
|
||||
};
|
|
@ -0,0 +1,67 @@
|
|||
#include "ContaminationDetection.h"
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
ContaminationDetection::ContaminationDetection()
|
||||
{
|
||||
}
|
||||
|
||||
int ContaminationDetection::detect1(const uchar *data1, const uchar *data2, int length, uchar threshold1, uchar threshold2, int width)
|
||||
{
|
||||
int width_temp = 0;
|
||||
for (size_t i = 0; i < length; i++)
|
||||
{
|
||||
if (MIN(data1[i], data2[i]) > threshold1)
|
||||
return 1;
|
||||
|
||||
if (MIN(data1[i], data2[i]) > threshold2)
|
||||
{
|
||||
width_temp++;
|
||||
if (width_temp > width)
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
width_temp = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ContaminationDetection::detect2(const uchar *data, int width, int height, int channels, uchar color, int length)
|
||||
{
|
||||
uchar *ptr = const_cast<uchar *>(data);
|
||||
std::vector<int> sum_threshold;
|
||||
sum_threshold.resize(height);
|
||||
|
||||
uchar table[256];
|
||||
memset(table, 1, 256);
|
||||
memset(table, 0, color);
|
||||
|
||||
int sum, bit_sum;
|
||||
for (size_t y = 0, bytePerLine = width * channels; y < height; y++)
|
||||
{
|
||||
sum = 0;
|
||||
for (size_t x = 0; x < bytePerLine; x += channels)
|
||||
{
|
||||
bit_sum = 0;
|
||||
for (size_t i = 0; i < channels; i++)
|
||||
bit_sum |= table[ptr[x + i]];
|
||||
|
||||
sum += bit_sum;
|
||||
}
|
||||
sum_threshold[y] = sum;
|
||||
ptr += bytePerLine;
|
||||
}
|
||||
|
||||
if (sum_threshold[0] > length || sum_threshold[height - 1] > length)
|
||||
{
|
||||
if (std::abs(sum_threshold[0] - sum_threshold[height - 1]) > 10)
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* ====================================================
|
||||
|
||||
* 功能:镜头脏污检测
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2023/10/09
|
||||
* 最近修改时间:2023/10/09 v1.0
|
||||
2023/11/08 v1.1 增加接口,对数据顶部和底部数据同时检测,避免受到纸张越界产生的误判。
|
||||
2023/12/05 v1.2 增加接口,通过判定多行数据,来确认脏污性质。
|
||||
2023/12/06 v1.2.1 微调接口2判定逻辑。
|
||||
* 版本号:v1.2.1
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#ifndef CONTAMINATION_DETECTION_H
|
||||
#define CONTAMINATION_DETECTION_H
|
||||
|
||||
typedef unsigned char uchar;
|
||||
|
||||
class ContaminationDetection
|
||||
{
|
||||
public:
|
||||
ContaminationDetection();
|
||||
|
||||
/// <summary>
|
||||
/// 检测
|
||||
/// </summary>
|
||||
/// <param name="data1">top行待测数据</param>
|
||||
/// <param name="data2">bottom行待测数据</param>
|
||||
/// <param name="length">数据长度</param>
|
||||
/// <param name="threshold1">第一阈值,超过该阈值视为存在脏污</param>
|
||||
/// <param name="threshold2">第二阈值,配合width使用,超过该阈值且连续宽度达到width视为存在脏污</param>
|
||||
/// <param name="width">脏污宽度,配合threshold2使用</param>
|
||||
/// <returns>为0时表示无污染,反之有污染。</returns>
|
||||
static int detect1(const uchar *data1, const uchar *data2, int length, uchar threshold1, uchar threshold2, int width);
|
||||
|
||||
/// <summary>
|
||||
/// 检测
|
||||
/// </summary>
|
||||
/// <param name="data">图像数据</param>
|
||||
/// <param name="width">像素宽度</param>
|
||||
/// <param name="height">高度</param>
|
||||
/// <param name="channels">通道数</param>
|
||||
/// <param name="color">超过该阈值视为存在脏污</param>
|
||||
/// <param name="length">脏污累计宽度</param>
|
||||
/// <returns>为0时表示无污染;为1时表示脏污无规则,可能由纸张遮挡造成;为2时表示脏污规则</returns>
|
||||
static int detect2(const uchar *data, int width, int height, int channels, uchar color, int length);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -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,32 @@
|
|||
#include "cvimagex.h"
|
||||
#include "opencv2/opencv.hpp"
|
||||
|
||||
CvImageX::CvImageX(MatPtr image)
|
||||
{
|
||||
this->image = image;
|
||||
}
|
||||
|
||||
unsigned char *CvImageX::data()
|
||||
{
|
||||
return image->data;
|
||||
}
|
||||
|
||||
int CvImageX::width()
|
||||
{
|
||||
return image->cols;
|
||||
}
|
||||
|
||||
int CvImageX::height()
|
||||
{
|
||||
return image->rows;
|
||||
}
|
||||
|
||||
int CvImageX::datasize()
|
||||
{
|
||||
return height() * image->step;
|
||||
}
|
||||
|
||||
int CvImageX::type()
|
||||
{
|
||||
return image->type();
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#include "imgproc.h"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
class Mat;
|
||||
}
|
||||
|
||||
typedef std::shared_ptr<cv::Mat> MatPtr;
|
||||
|
||||
class CvImageX : public IImage
|
||||
{
|
||||
public:
|
||||
CvImageX(MatPtr image);
|
||||
virtual unsigned char *data();
|
||||
virtual int width();
|
||||
virtual int height();
|
||||
virtual int type();
|
||||
virtual int datasize();
|
||||
|
||||
private:
|
||||
MatPtr image;
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class IImage
|
||||
{
|
||||
public:
|
||||
virtual ~IImage() {}
|
||||
|
||||
virtual unsigned char *data() = 0;
|
||||
virtual int width() = 0;
|
||||
virtual int height() = 0;
|
||||
virtual int type() = 0;
|
||||
virtual int stride() = 0;
|
||||
virtual int datasize() = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<IImage> IImagePtr;
|
||||
|
||||
class IImagePair
|
||||
{
|
||||
public:
|
||||
IImagePair(IImagePtr imagef, IImagePtr imageb)
|
||||
{
|
||||
this->imagef = imagef;
|
||||
this->imageb = imageb;
|
||||
}
|
||||
|
||||
IImagePtr imagef;
|
||||
IImagePtr imageb;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<IImagePair> IImagePairPtr;
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
#include "imemory.h"
|
||||
#include "imgproc.h"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
class Mat;
|
||||
}
|
||||
|
||||
class IImageEncode
|
||||
{
|
||||
public:
|
||||
virtual ~IImageEncode() {}
|
||||
|
||||
virtual MemoryPtr encode(cv::Mat &image) = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<IImageEncode> ImageEncodePtr;
|
|
@ -0,0 +1,52 @@
|
|||
#include "imageencode.h"
|
||||
#include "memoryex.h"
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include "StopWatch.h"
|
||||
|
||||
BmpImageEncode::~BmpImageEncode()
|
||||
{
|
||||
}
|
||||
|
||||
MemoryPtr BmpImageEncode::encode(cv::Mat &image)
|
||||
{
|
||||
VectorMemroyPtr mem = VectorMemroyPtr(new VectorMemroy());
|
||||
// StopWatch sw;
|
||||
cv::imencode(".bmp", image, mem->buf());
|
||||
// printf("encode time = %0.2f \n", sw.elapsed_ms());
|
||||
return mem;
|
||||
}
|
||||
|
||||
JpegImageEncode::JpegImageEncode(bool bwimg)
|
||||
{
|
||||
if (!bwimg)
|
||||
{
|
||||
compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
|
||||
compression_params.push_back(100);
|
||||
}
|
||||
else
|
||||
{
|
||||
compression_params.push_back(CV_IMWRITE_PNG_STRATEGY);
|
||||
compression_params.push_back(cv::IMWRITE_PNG_STRATEGY_FIXED);
|
||||
}
|
||||
m_bwimg = bwimg;
|
||||
}
|
||||
|
||||
JpegImageEncode::~JpegImageEncode()
|
||||
{
|
||||
}
|
||||
MemoryPtr JpegImageEncode::encode(cv::Mat &image)
|
||||
{
|
||||
VectorMemroyPtr mem = VectorMemroyPtr(new VectorMemroy());
|
||||
// StopWatch sw;
|
||||
cv::imencode(m_bwimg ? ".png" : ".jpg", image, mem->buf(), compression_params);
|
||||
// printf("encode time = %0.2f \n", sw.elapsed_ms());
|
||||
return mem;
|
||||
}
|
||||
|
||||
MemoryPtr buff2mem(void *data, int size)
|
||||
{
|
||||
auto mem = std::shared_ptr<VectorMemroy>(new VectorMemroy());
|
||||
mem->buf().resize(size);
|
||||
// memcpy(mem->buf().data(), data, size);
|
||||
return mem;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
#include "iimageencode.h"
|
||||
#include <vector>
|
||||
|
||||
// typedef struct tagBITMAPFILEHEADER {
|
||||
// WORD bfType;
|
||||
// DWORD bfSize;
|
||||
// WORD bfReserved1;
|
||||
// WORD bfReserved2;
|
||||
// DWORD bfOffBits;
|
||||
// } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
|
||||
|
||||
class BmpImageEncode : public IImageEncode
|
||||
{
|
||||
public:
|
||||
virtual ~BmpImageEncode();
|
||||
|
||||
virtual MemoryPtr encode(cv::Mat &image);
|
||||
};
|
||||
|
||||
class JpegImageEncode : public IImageEncode
|
||||
{
|
||||
public:
|
||||
JpegImageEncode(bool bwimg);
|
||||
virtual ~JpegImageEncode();
|
||||
virtual MemoryPtr encode(cv::Mat &image);
|
||||
|
||||
private:
|
||||
std::vector<int> compression_params;
|
||||
bool m_bwimg;
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 8c7759dba203f0a01d586d8c8174df54fcda7602
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
// #include <FreeImagePlus.h>
|
||||
|
||||
class IMemory
|
||||
{
|
||||
public:
|
||||
virtual ~IMemory() {}
|
||||
|
||||
virtual unsigned char *data() = 0;
|
||||
virtual size_t size() = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<IMemory> MemoryPtr;
|
||||
|
||||
MemoryPtr buff2mem(void *data, int size);
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include "iimage.h"
|
||||
|
||||
class IImPorc
|
||||
{
|
||||
public:
|
||||
virtual ~IImPorc() {}
|
||||
virtual IImagePairPtr proc(IImagePairPtr image) = 0;
|
||||
};
|
||||
|
||||
class IImageWrite
|
||||
{
|
||||
public:
|
||||
virtual ~IImageWrite() {}
|
||||
|
||||
virtual bool save(std::string path, std::vector<int> params) = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<IImageWrite> ImageWritePtr;
|
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
#include "imemory.h"
|
||||
|
||||
class VectorMemroy : public IMemory
|
||||
{
|
||||
public:
|
||||
virtual unsigned char *data()
|
||||
{
|
||||
return m_data.empty() ? nullptr : &m_data[0];
|
||||
}
|
||||
|
||||
virtual size_t size()
|
||||
{
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
std::vector<unsigned char> &buf()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void resize(int size)
|
||||
{
|
||||
m_data.resize(size);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<unsigned char> m_data;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<VectorMemroy> VectorMemroyPtr;
|
||||
|
||||
// class FipMemory : public IMemory
|
||||
// {
|
||||
// public:
|
||||
// FipMemory(){}
|
||||
// virtual unsigned char *data()
|
||||
// {
|
||||
// unsigned char *p;
|
||||
// DWORD size;
|
||||
// mio.acquire(&p, &size);
|
||||
// return p;
|
||||
// }
|
||||
|
||||
// virtual size_t size()
|
||||
// {
|
||||
// unsigned char *p;
|
||||
// DWORD size;
|
||||
// mio.acquire(&p, &size);
|
||||
// return size;
|
||||
// }
|
||||
|
||||
// fipMemoryIO &io()
|
||||
// {
|
||||
// return mio;
|
||||
// }
|
||||
|
||||
// private:
|
||||
// fipMemoryIO mio;
|
||||
// };
|
||||
|
||||
// typedef std::shared_ptr<FipMemory> FipMemoryPtr;
|
|
@ -0,0 +1,18 @@
|
|||
project(keymonitor)
|
||||
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} ${DIR_SUBSRC})
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_SOURCE_DIR}/../packages/common.pkg/include
|
||||
${PROJECT_SOURCE_DIR}/../deviceio
|
||||
)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
|
|
@ -0,0 +1,204 @@
|
|||
#include "keymonitor.h"
|
||||
#include "Gpio.h"
|
||||
#include "PinMonitor.h"
|
||||
#include <iostream>
|
||||
|
||||
#define STATUS_SUCCESS 0
|
||||
#define STATUS_FAILURE -1
|
||||
|
||||
#define CH455_GET_KEY 0x0700 // 获取按键,返回按键代码
|
||||
#define CH455_SYSOFF 0x0400 // 关闭显示、关闭键盘
|
||||
|
||||
#define CH455_I2C_ADDR 0x40 // CH455的地址
|
||||
#define CH455_I2C_MASK 0x3E // CH455的高字节命令掩码
|
||||
|
||||
#define CH455_BIT_ENABLE 0x01
|
||||
//#define CH455_BIT_ENABLE 0x03 // 开启/关闭位
|
||||
#define CH455_BIT_SLEEP 0x04 // 睡眠控制位
|
||||
|
||||
|
||||
#define CH455_SYSON ( CH455_SYSOFF | CH455_BIT_ENABLE )
|
||||
#define CH455_SLEEPOFF CH455_SYSOFF // 关闭睡眠
|
||||
#define CH455_SLEEPON (CH455_SYSOFF|CH455_BIT_SLEEP) // 开启睡眠
|
||||
|
||||
KeyMonitor::KeyMonitor(std::function<void(int)> keycall) : m_keycall(keycall)
|
||||
{
|
||||
m_gpioi2c_SCL = std::make_shared<Gpio>(44); //I2C_SCL
|
||||
m_gpioi2c_SCL->setDirection(Gpio::out);
|
||||
m_gpioi2c_SDA = std::make_shared<Gpio>(43); //I2C_SDA
|
||||
m_gpioi2c_SDA->setDirection(Gpio::out);
|
||||
write_cmd(CH455_SYSON);
|
||||
printf("read_key = %02x\n", read_key());
|
||||
setled(HGLed::Led_All_close);
|
||||
auto pincall=[&](int pin)
|
||||
{
|
||||
auto value= read_key();
|
||||
printf("Key = %02x pin value = %d \n",value,pin);
|
||||
if(m_keycall)
|
||||
m_keycall(value);
|
||||
};
|
||||
m_keymonitor = std::make_shared<PinMonitor>(52,pincall);
|
||||
}
|
||||
|
||||
KeyMonitor::~KeyMonitor()
|
||||
{
|
||||
if(m_gpioi2c_SCL.get())
|
||||
m_gpioi2c_SCL.reset();
|
||||
|
||||
if(m_gpioi2c_SDA.get())
|
||||
m_gpioi2c_SDA.reset();
|
||||
|
||||
if(m_keymonitor.get())
|
||||
m_keymonitor.reset();
|
||||
}
|
||||
|
||||
void KeyMonitor::init()
|
||||
{
|
||||
}
|
||||
|
||||
void KeyMonitor::i2c_start()
|
||||
{
|
||||
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::Low);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
}
|
||||
|
||||
void KeyMonitor::i2c_write(unsigned char cmd)
|
||||
{
|
||||
unsigned char i;
|
||||
for(i=0; i<8; i++)
|
||||
{
|
||||
//IOWR(I2C_SCL, 0); //钳住I2C总线,准备发送数据
|
||||
if(cmd & 0x80)
|
||||
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
|
||||
else
|
||||
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::Low);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
cmd<<=1;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
}
|
||||
|
||||
unsigned char KeyMonitor::i2c_read()
|
||||
{
|
||||
unsigned char bytedata = 0;
|
||||
m_gpioi2c_SDA->setDirection(Gpio::in);//将数据设置为输入模式
|
||||
//m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
bytedata <<= 1;
|
||||
bytedata = bytedata | (m_gpioi2c_SDA->getValue());
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
}
|
||||
m_gpioi2c_SDA->setDirection(Gpio::out);
|
||||
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);////数据线设置回输出模式
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
return bytedata;
|
||||
}
|
||||
|
||||
void KeyMonitor::i2c_stop()
|
||||
{
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::Low);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(5));
|
||||
}
|
||||
|
||||
void KeyMonitor::write_cmd(unsigned short cmd)
|
||||
{
|
||||
i2c_start();
|
||||
i2c_write(((unsigned char)(cmd>>7)&CH455_I2C_MASK)|CH455_I2C_ADDR);
|
||||
i2c_write(cmd);
|
||||
i2c_stop();
|
||||
}
|
||||
|
||||
unsigned char KeyMonitor::read_key()
|
||||
{
|
||||
unsigned char key=0;
|
||||
i2c_start();
|
||||
i2c_write((unsigned char)(CH455_GET_KEY>>7)&CH455_I2C_MASK|0x01|CH455_I2C_ADDR);
|
||||
key = i2c_read();
|
||||
i2c_stop();
|
||||
return key;
|
||||
}
|
||||
|
||||
std::uint8_t KeyMonitor::getledstate()
|
||||
{
|
||||
return m_ledstate;
|
||||
}
|
||||
|
||||
void KeyMonitor::setled(HGLed value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case HGLed::Led_All_close:
|
||||
m_ledstate = 0;
|
||||
break;
|
||||
#ifdef G200
|
||||
case HGLed::Led_All_open:
|
||||
m_ledstate = 0xf8;
|
||||
break;
|
||||
case HGLed::Led_Count_close:
|
||||
m_ledstate = m_ledstate & 0xef;
|
||||
break;
|
||||
case HGLed::Led_Count_open:
|
||||
m_ledstate = m_ledstate | 0x10;
|
||||
break;
|
||||
case HGLed::Led_DoubleFeed_close:
|
||||
m_ledstate = m_ledstate & 0xbf;
|
||||
break;
|
||||
case HGLed::Led_DoubleFeed_open:
|
||||
m_ledstate = m_ledstate | 0x40;
|
||||
break;
|
||||
case HGLed::Led_Enter_close:
|
||||
m_ledstate = m_ledstate & 0xf7;
|
||||
break;
|
||||
case HGLed::Led_Enter_open:
|
||||
m_ledstate = m_ledstate | 0x8;
|
||||
break;
|
||||
case HGLed::Led_Handle_close:
|
||||
m_ledstate = m_ledstate & 0xdf;
|
||||
break;
|
||||
case HGLed::Led_Handle_open:
|
||||
m_ledstate = m_ledstate | 0x20;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
i2c_start();
|
||||
i2c_write(0x6e);
|
||||
i2c_write(m_ledstate);
|
||||
i2c_stop();
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include "commondef.h"
|
||||
class PinMonitor;
|
||||
class Gpio;
|
||||
|
||||
class KeyMonitor
|
||||
{
|
||||
public:
|
||||
#ifdef G200
|
||||
enum class HGKey
|
||||
{
|
||||
Key_Enter = 69,
|
||||
Key_Cancle = 70,
|
||||
Key_Count = 78,
|
||||
Key_Handle = 77,
|
||||
Key_DoubleFeed = 68,
|
||||
Key_Left = 86,
|
||||
Key_Menu = 85,
|
||||
Key_Right = 76,
|
||||
Key_Clear = 84
|
||||
};
|
||||
#else
|
||||
enum class HGKey
|
||||
{
|
||||
Key_Enter = 70,
|
||||
Key_Cancle = 69,
|
||||
Key_Count = 78,
|
||||
Key_Menu = 76,
|
||||
Key_Right = 77,
|
||||
Key_Clear = 68,
|
||||
Key_Handle = 3331,
|
||||
Key_DoubleFeed = 3332,
|
||||
Key_Left = 3333
|
||||
};
|
||||
#endif
|
||||
enum class HGLed
|
||||
{
|
||||
Led_Enter_open = 0,
|
||||
Led_Enter_close,
|
||||
Led_Count_open,
|
||||
Led_Count_close,
|
||||
Led_DoubleFeed_open,
|
||||
Led_DoubleFeed_close,
|
||||
Led_Handle_open,
|
||||
Led_Handle_close,
|
||||
Led_All_open,
|
||||
Led_All_close
|
||||
};
|
||||
public:
|
||||
KeyMonitor(std::function<void(int)> keycall);
|
||||
void setled(HGLed value);
|
||||
std::uint8_t getledstate();
|
||||
~KeyMonitor();
|
||||
private:
|
||||
void init();
|
||||
void i2c_start();
|
||||
void i2c_write(unsigned char cmd);
|
||||
unsigned char i2c_read();
|
||||
void i2c_stop();
|
||||
void write_cmd(unsigned short cmd);
|
||||
unsigned char read_key();
|
||||
private:
|
||||
std::shared_ptr<PinMonitor> m_keymonitor;
|
||||
std::shared_ptr<Gpio> m_gpioi2c_SDA;
|
||||
std::shared_ptr<Gpio> m_gpioi2c_SCL;
|
||||
std::function<void(int)> m_keycall;
|
||||
volatile std::uint8_t m_ledstate;
|
||||
};
|
|
@ -0,0 +1,48 @@
|
|||
#include <sched.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <thread>
|
||||
|
||||
void test()
|
||||
{
|
||||
auto _start = std::chrono::steady_clock::now();
|
||||
int arr[1000000];
|
||||
for (size_t i = 0; i < 1000000; i++)
|
||||
{
|
||||
for (size_t j = 0; j < 1000; j++)
|
||||
{
|
||||
arr[i] = i;
|
||||
}
|
||||
}
|
||||
auto times = std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - _start).count();
|
||||
printf("times = %.2f \n", times);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct sched_param param;
|
||||
int maxpri;
|
||||
maxpri = sched_get_priority_max(SCHED_FIFO); //»ñÈ¡×î´óÖµ
|
||||
if (maxpri == -1)
|
||||
{
|
||||
printf("sched_get_priority_max() failed \n");
|
||||
exit(1);
|
||||
}
|
||||
printf("%d \n", maxpri);
|
||||
param.sched_priority = maxpri;
|
||||
std::thread threadaa(test);
|
||||
// if (sched_setscheduler(getpid(), SCHED_FIFO, ¶m) == -1) //设置优先级
|
||||
// {
|
||||
// printf("sched_setscheduler() failed \n");
|
||||
// exit(1);
|
||||
// }
|
||||
// if(pthread_setschedparam(threadaa.native_handle(),SCHED_FIFO,¶m))
|
||||
// {
|
||||
// printf("sched_setscheduler() failed \n");
|
||||
// exit(1);
|
||||
// }
|
||||
threadaa.join();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
project(motorboard)
|
||||
add_compile_options(-std=c++14)
|
||||
|
||||
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})
|
||||
if(CMAKE_HOST_WIN32)
|
||||
link_libraries(
|
||||
libopencv_world.a
|
||||
liblibjasper.a
|
||||
libittnotify.a
|
||||
libtegra_hal.a
|
||||
libzlib.a
|
||||
liblibjpeg-turbo.a
|
||||
liblibpng.a
|
||||
liblibtiff.a
|
||||
liblibwebp.a
|
||||
)
|
||||
else()
|
||||
link_libraries(
|
||||
opencv_core
|
||||
opencv_imgproc
|
||||
opencv_imgcodecs
|
||||
)
|
||||
endif()
|
||||
add_library(${PROJECT_NAME} STATIC ${DIR_SRCS})
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_SOURCE_DIR}/../packages/common.pkg/include
|
||||
${PROJECT_SOURCE_DIR}/../deviceio
|
||||
${PROJECT_SOURCE_DIR}/../regs
|
||||
${PROJECT_SOURCE_DIR}/../applog
|
||||
${PROJECT_SOURCE_DIR}/../capimage
|
||||
${PROJECT_SOURCE_DIR}/../motorcontroller
|
||||
${PROJECT_SOURCE_DIR}/../scanner
|
||||
${PROJECT_SOURCE_DIR}/../display
|
||||
)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
|
|
@ -0,0 +1,69 @@
|
|||
#include "FeedControl.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
FeedControl::FeedControl(/* args */) : m_thre(0.3)
|
||||
{
|
||||
}
|
||||
|
||||
FeedControl::~FeedControl()
|
||||
{
|
||||
}
|
||||
|
||||
FeedControl::FeedMode FeedControl::GetPredictFeedMode()
|
||||
{
|
||||
return calcFeedMode();
|
||||
}
|
||||
|
||||
FeedControl::FeedMode FeedControl::calcFeedMode()
|
||||
{
|
||||
FeedMode mode = FeedMode::FMode_NOChange;
|
||||
auto infos = m_sessioninfo.GetRecordInfo();
|
||||
if (infos.size() < 10) //样本数量大于10了 才做分纸模式分析切换
|
||||
return mode;
|
||||
|
||||
unsigned int nDoubleFeedTimes, nJamTimes, nFeedErrorTimes, nTotalScanned;
|
||||
nDoubleFeedTimes = nJamTimes = nFeedErrorTimes = nTotalScanned = 0;
|
||||
for (auto &item : infos)
|
||||
{
|
||||
if (!item.NormalDone)
|
||||
{
|
||||
if (item.DoubleFeed)
|
||||
nDoubleFeedTimes++;
|
||||
if (item.Jammed)
|
||||
nJamTimes++;
|
||||
if (item.FeedError)
|
||||
nFeedErrorTimes++;
|
||||
|
||||
nTotalScanned += item.CurrentScaned;
|
||||
}
|
||||
}
|
||||
|
||||
double percentHigh = nDoubleFeedTimes / 10.0;
|
||||
double percentLow = nFeedErrorTimes / 10.0;
|
||||
printf("\n percentHigh : %f percentLow : %f" , percentHigh,percentLow);
|
||||
if (percentHigh >= m_thre || percentLow >= m_thre)
|
||||
{
|
||||
mode = percentHigh >= percentLow ? FeedMode::FMode_High : FeedMode::FMode_Low;
|
||||
if(fabs(percentHigh - percentLow) < 0.2)
|
||||
mode = FeedMode::FMode_Mid;
|
||||
ResetMode();
|
||||
}
|
||||
printf("\n Calc Feed Mode : %d" , (int)mode);
|
||||
return mode;
|
||||
}
|
||||
|
||||
void FeedControl::AppendPattern(MotorSessionInfo::MBTaskRecordInfo info)
|
||||
{
|
||||
m_sessioninfo.UpdateRecordInfo(info);
|
||||
}
|
||||
|
||||
void FeedControl::SetThre(double thre)
|
||||
{
|
||||
m_thre = thre;
|
||||
}
|
||||
|
||||
void FeedControl::ResetMode()
|
||||
{
|
||||
m_sessioninfo.RemoveInfos();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue