initial commit

This commit is contained in:
masayume_ht 2024-03-05 11:46:18 +08:00
commit ed2576f160
304 changed files with 66689 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.vscode/*
.cmake/*
.xmake/*
build/*
app.log

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "imgproc/imageprocess"]
path = imgproc/imageprocess
url = https://gitee.com/huagaochina/ImageProcess.git

52
CMakeLists.txt Normal file
View File

@ -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)

BIN
anlogic Normal file

Binary file not shown.

16
applog/CMakeLists.txt Normal file
View File

@ -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)

121
applog/applog.cpp Normal file
View File

@ -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;
}

20
applog/applog.h Normal file
View File

@ -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);

301
capimage/CImageMerge.cpp Normal file
View File

@ -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;
}

15
capimage/CImageMerge.h Normal file
View File

@ -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);
};

20
capimage/CMakeLists.txt Normal file
View File

@ -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)

67
capimage/CameraParam.h Normal file
View File

@ -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;
};

845
capimage/Capturer.cpp Normal file
View File

@ -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;
}

70
capimage/Capturer.h Normal file
View File

@ -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;
};

856
capimage/CorrectParam.cpp Normal file
View File

@ -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 &param)
{
j = json{{"ExposureF", param.ExposureF},
{"GainF", param.GainF},
{"OffsetF", param.OffsetF},
{"ExposureB", param.ExposureB},
{"GainB", param.GainB},
{"OffsetB", param.OffsetB},
{"DpiMode", param.DpiMode},
{"ColorMode", param.ColorMode},
{"MaxBright", param.MaxBright},
{"MaxExp", param.MaxExp},
{"Sp", param.Sp},
{"HRatio", param.HRatio},
{"VRatio", param.VRatio},
{"LutPath", param.LutPath},
{"TextLutPath", param.TextLutPath},
{"FlatBlackPath", param.Flat_BwPath},
{"FlatWhitePath", param.Flat_WhitePath}};
}
void CorrectParam::from_json(json &j, FPGAConfigParam &param)
{
j.at("ExposureF").get_to(param.ExposureF);
j.at("GainF").get_to(param.GainF);
j.at("OffsetF").get_to(param.OffsetF);
j.at("ExposureB").get_to(param.ExposureB);
j.at("GainB").get_to(param.GainB);
j.at("OffsetB").get_to(param.OffsetB);
j.at("DpiMode").get_to(param.DpiMode);
j.at("ColorMode").get_to(param.ColorMode);
j.at("MaxBright").get_to(param.MaxBright);
j.at("MaxExp").get_to(param.MaxExp);
j.at("Sp").get_to(param.Sp);
j.at("HRatio").get_to(param.HRatio);
j.at("VRatio").get_to(param.VRatio);
j.at("LutPath").get_to(param.LutPath);
j.at("TextLutPath").get_to(param.TextLutPath);
j.at("FlatBlackPath").get_to(param.Flat_BwPath);
j.at("FlatWhitePath").get_to(param.Flat_WhitePath);
}
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 &param)
{
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 &param)
{
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;

51
capimage/CorrectParam.h Normal file
View File

@ -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 &param);
void from_json(json &j, FPGAConfigParam &param);
std::vector<FPGAConfigParam_8478> GetCorrectParams_8478();
std::vector<FPGAConfigParam_8478> GetCorrectParams_8478_HL_Lvds();
void to_json(json &j, FPGAConfigParam_8478 &param);
void from_json(json &j, FPGAConfigParam_8478 &param);
std::mutex m_lock;
};
extern CorrectParam m_static_correctparam;
static CorrectParam& Get_Static_CorrectParam()
{
return m_static_correctparam;
}

495
capimage/FpgaComm.cpp Normal file
View File

@ -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);
}

217
capimage/FpgaComm.h Normal file
View File

@ -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;
};

109
capimage/GrayLighting.h Normal file
View File

@ -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]];
}

52
capimage/ICapturer.h Normal file
View File

@ -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;
};

1045
capimage/MonoCapturer.cpp Normal file

File diff suppressed because it is too large Load Diff

74
capimage/MonoCapturer.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
};
};

182
capimage/SysInforTool.cpp Normal file
View File

@ -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;
}

28
capimage/SysInforTool.h Normal file
View File

@ -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;
};

658
capimage/correct_ultis.cpp Normal file
View File

@ -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 &param)
{
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;
}

45
capimage/correct_ultis.h Normal file
View File

@ -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 &param);
cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, int dpi, bool colormode);

127
capimage/deviceconfig.cpp Normal file
View File

@ -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;
}

65
capimage/deviceconfig.h Normal file
View File

@ -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;
}

348
capimage/gvideo.cpp Normal file
View File

@ -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());
}

49
capimage/gvideo.h Normal file
View File

@ -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;
};

918
capimage/gvideoisp1.cpp Normal file
View File

@ -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();
}
}

24
capimage/gvideoisp1.h Normal file
View File

@ -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";
};

316
capimage/hgutils.cpp Normal file
View File

@ -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();
}

33
capimage/hgutils.h Normal file
View File

@ -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();

442
capimage/jsonconfig.cpp Normal file
View File

@ -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;
}

31
capimage/jsonconfig.h Normal file
View File

@ -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;
}

69
capimage/scannersysinfo.h Normal file
View File

@ -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;

165
changelog.txt Normal file
View File

@ -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.适配9000afpgavsp调整为7580 -23.03.11
6.更新色偏矫正算法
7.调整9000a版本vsp为80120 -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

10
config.h.in Normal file
View File

@ -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

16
deviceio/CMakeLists.txt Normal file
View File

@ -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)

32
deviceio/DevUtil.cpp Normal file
View File

@ -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);
}

94
deviceio/DevUtil.h Normal file
View File

@ -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};
};

95
deviceio/Gpio.cpp Normal file
View File

@ -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);
}

52
deviceio/Gpio.h Normal file
View File

@ -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);
};

45
deviceio/Led.cpp Normal file
View File

@ -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);
}

24
deviceio/Led.h Normal file
View File

@ -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";
};

76
deviceio/PinMonitor.cpp Normal file
View File

@ -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);
}

19
deviceio/PinMonitor.h Normal file
View File

@ -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;
};

38
deviceio/Pwm.cpp Normal file
View File

@ -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);
}

22
deviceio/Pwm.h Normal file
View File

@ -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";
};

8
deviceio/xmake.lua Normal file
View File

@ -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")

18
display/CMakeLists.txt Normal file
View File

@ -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)

61
display/DisplayCenter.cpp Normal file
View File

@ -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);
}

31
display/DisplayCenter.h Normal file
View File

@ -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;
};

83
display/Displaydef.h Normal file
View File

@ -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;
};

1186
display/HgLCDfont.h Normal file

File diff suppressed because it is too large Load Diff

189
display/LCDDisplay.cpp Normal file
View File

@ -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;
}

205
display/LCDDisplay.h Normal file
View File

@ -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))}},
};
};

780
display/Lcd.cpp Normal file
View File

@ -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粗调对比度可设置范围0x200x27*/
Lcd_Transfer_Command(0x81); /*微调对比度*/
Lcd_Transfer_Command(biglcd?0x28:0x15); /*45微调对比度的值可设置范围0x000x3f 1f*/ // 0~63
Lcd_Transfer_Command(0xa2); /*1/9偏压比bias0xa2 ,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);
}

61
display/Lcd.h Normal file
View File

@ -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);
};

21
fpgaupdate/CMakeLists.txt Normal file
View File

@ -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)

121
fpgaupdate/fpgacontrol.cpp Normal file
View File

@ -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;
}
}

23
fpgaupdate/fpgacontrol.h Normal file
View File

@ -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;
};

1525
fpgaupdate/libmtd.c Normal file

File diff suppressed because it is too large Load Diff

358
fpgaupdate/libmtd.h Normal file
View File

@ -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__ */

247
fpgaupdate/libmtd_common.h Normal file
View File

@ -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__ */

110
fpgaupdate/libmtd_int.h Normal file
View File

@ -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__ */

404
fpgaupdate/libmtd_legacy.c Normal file
View File

@ -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);
}

100
fpgaupdate/libmtd_xalloc.h Normal file
View File

@ -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__ */

6
i2c_key/Makefile Normal file
View File

@ -0,0 +1,6 @@
ch455_key:ch455_key.cpp
g++ $^ -o $@
clean:
rm ch455_key

BIN
i2c_key/ch455_key Normal file

Binary file not shown.

330
i2c_key/ch455_key.cpp Normal file
View File

@ -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;
}

32
imgproc/CMakeLists.txt Normal file
View File

@ -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)

285
imgproc/CSizedetect.cpp Normal file
View File

@ -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;
}

42
imgproc/CSizedetect.h Normal file
View File

@ -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}}};
};

View File

@ -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;
}

View File

@ -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

5
imgproc/IPreproc.cpp Normal file
View File

@ -0,0 +1,5 @@
#include "IPreproc.h"
IPreproc::IPreproc(void) {}
IPreproc::~IPreproc(void) {}

13
imgproc/IPreproc.h Normal file
View File

@ -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;
};

32
imgproc/cvimagex.cpp Normal file
View File

@ -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();
}

22
imgproc/cvimagex.h Normal file
View File

@ -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;
};

34
imgproc/iimage.h Normal file
View File

@ -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;

18
imgproc/iimageencode.h Normal file
View File

@ -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;

52
imgproc/imageencode.cpp Normal file
View File

@ -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;
}

31
imgproc/imageencode.h Normal file
View File

@ -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;
};

1
imgproc/imageprocess Submodule

@ -0,0 +1 @@
Subproject commit 8c7759dba203f0a01d586d8c8174df54fcda7602

17
imgproc/imemory.h Normal file
View File

@ -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);

19
imgproc/imgproc.h Normal file
View File

@ -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;

62
imgproc/memoryex.h Normal file
View File

@ -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;

18
keymonitor/CMakeLists.txt Normal file
View File

@ -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)

204
keymonitor/keymonitor.cpp Normal file
View File

@ -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();
}

71
keymonitor/keymonitor.h Normal file
View File

@ -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;
};

48
main.cpp Normal file
View File

@ -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, &param) == -1) //设置优先级
// {
// printf("sched_setscheduler() failed \n");
// exit(1);
// }
// if(pthread_setschedparam(threadaa.native_handle(),SCHED_FIFO,&param))
// {
// printf("sched_setscheduler() failed \n");
// exit(1);
// }
threadaa.join();
return 0;
}

39
motorboard/CMakeLists.txt Normal file
View File

@ -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)

View File

@ -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