mirror of http://192.168.1.51:8099/lmh188/twain3.0
546 lines
13 KiB
C++
546 lines
13 KiB
C++
#include "stdafx.h"
|
||
#include "GDevice.h"
|
||
#include "IUsb.h"
|
||
#include <cstdio>
|
||
#include <iostream>
|
||
#include <algorithm>
|
||
#include <set>
|
||
#include <string.h>
|
||
#include <fstream>
|
||
#include <iterator>
|
||
#include <sstream>
|
||
#include "StopWatch.h"
|
||
#include "device_common.h"
|
||
#include "GScan200.h"
|
||
|
||
#ifndef WIN32
|
||
#include <unistd.h>
|
||
#endif
|
||
|
||
#include <windows.h>
|
||
|
||
#define DSP_CODE_ADDR 0
|
||
#define USER_ADDR 0x4000
|
||
|
||
using namespace std;
|
||
//class GScan200;
|
||
|
||
|
||
GDevice::GDevice(std::shared_ptr<IUsb> usb)
|
||
{
|
||
m_bScan = false;
|
||
m_bListen = false;
|
||
m_usb = usb;
|
||
event_call = NULL;
|
||
image_call = NULL;
|
||
m_imagecall_userdata = NULL;
|
||
m_eventcall_userdata = NULL;
|
||
m_threadInt = NULL;
|
||
m_threadrecv = NULL;
|
||
m_run = false;
|
||
}
|
||
|
||
GDevice::~GDevice()
|
||
{
|
||
close();
|
||
}
|
||
|
||
bool GDevice::open()
|
||
{
|
||
if (is_open())
|
||
return true;
|
||
|
||
if (m_usb && m_usb->open()) {
|
||
m_usb->set_timeout(1000);
|
||
init_cam();
|
||
m_bListen = true;
|
||
m_bScan = true;
|
||
|
||
if (m_threadInt) {
|
||
m_bListen = false;
|
||
m_threadInt->join();
|
||
}
|
||
|
||
if (m_threadrecv) {
|
||
m_bScan = false;
|
||
m_threadrecv->join();
|
||
}
|
||
m_bListen = true;
|
||
m_bScan = true;
|
||
m_threadInt = std::shared_ptr<std::thread>(new std::thread(&GDevice::Int_main, this));
|
||
m_threadrecv = std::shared_ptr<std::thread>(new std::thread(&GDevice::recv_main, this));
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void GDevice::close()
|
||
{
|
||
if (m_usb.get() && m_usb->is_open()) {
|
||
m_usb->set_timeout(100);
|
||
stop();
|
||
|
||
if (m_threadInt && m_threadInt->joinable()) {
|
||
m_bListen = false;
|
||
this_thread::sleep_for(std::chrono::milliseconds(100));
|
||
m_threadInt->join();
|
||
m_threadInt = NULL;
|
||
}
|
||
|
||
if (m_threadrecv && m_threadrecv->joinable()) {
|
||
m_bScan = false;
|
||
image_indexs.ShutDown();
|
||
m_threadrecv->join();
|
||
m_threadrecv = NULL;
|
||
}
|
||
m_usb->close();
|
||
}
|
||
}
|
||
|
||
bool GDevice::is_open()
|
||
{
|
||
if (m_usb.get())
|
||
return m_usb->is_open();
|
||
return false;
|
||
}
|
||
|
||
bool GDevice::start(image_callback callfunc, void* userdata)
|
||
{
|
||
if (is_run())
|
||
return false;
|
||
|
||
image_call = callfunc;
|
||
m_imagecall_userdata = userdata;
|
||
MotorSetting ms;
|
||
ms.value = read_reg(MOTOR_BOARD, 0x00);
|
||
ms.scan_enable = 0;
|
||
write_reg(MOTOR_BOARD, 0x00, ms.value);
|
||
ms.scan_enable = 1;
|
||
write_reg(MOTOR_BOARD, 0x00, ms.value);
|
||
m_run = true;
|
||
return true;
|
||
}
|
||
|
||
void GDevice::set_event_call(event_callback callfunc, void* userdata)
|
||
{
|
||
m_eventcall_userdata = userdata;
|
||
event_call = callfunc;
|
||
}
|
||
|
||
void GDevice::stop()
|
||
{
|
||
set_option(Cam_Options::scanner_stop_motor, 0);
|
||
}
|
||
|
||
int GDevice::is_run()
|
||
{
|
||
return m_run;
|
||
}
|
||
|
||
void GDevice::reset()
|
||
{
|
||
|
||
}
|
||
|
||
static std::string read_all_from(std::string path)
|
||
{
|
||
int t;
|
||
FILE* file = fopen(path.c_str(), "rb");
|
||
fseek(file, 0, SEEK_END);
|
||
t = ftell(file);
|
||
std::string buf(t, 0);
|
||
fseek(file, 0, SEEK_SET);
|
||
fread((void*)buf.c_str(), t, 1, file);
|
||
fclose(file);
|
||
return buf;
|
||
}
|
||
|
||
void GDevice::write_dsp_fw(std::string path)
|
||
{
|
||
std::string buf = read_all_from(path);
|
||
write_flash(DSP_CODE_ADDR, (void*)buf.c_str(), buf.size());
|
||
}
|
||
|
||
void GDevice::write_pid(unsigned short pid)
|
||
{
|
||
write_flash(PID_ADDR, &pid, sizeof(pid));
|
||
}
|
||
|
||
unsigned short GDevice::read_pid()
|
||
{
|
||
unsigned short pid;
|
||
read_flash(PID_ADDR, &pid, sizeof(pid));
|
||
return pid;
|
||
}
|
||
|
||
|
||
void GDevice::write_devname(std::string name)
|
||
{
|
||
if (name.size() > 64)
|
||
return;
|
||
|
||
write_flash(DEVNAME_ADDR, (void*)name.c_str(), name.size());
|
||
}
|
||
|
||
std::string GDevice::read_devname()
|
||
{
|
||
char devname[65] = {0};
|
||
read_flash(DEVNAME_ADDR, devname, sizeof(devname) - 1);
|
||
return devname;
|
||
}
|
||
|
||
bool GDevice::write_flash(unsigned int addr, void* data, int size)
|
||
{
|
||
unsigned int writeAddr = addr;
|
||
int writed = 0;
|
||
int writing = 0;
|
||
while (writed < size) {
|
||
writing = min(crtlBufferSize, size - writed);
|
||
writeAddr = addr + writed;
|
||
{
|
||
std::lock_guard<std::mutex> lck(m_mtxCtrl);
|
||
m_usb->control_msg(to_device, flash_access, ((Reg2Short*)&writeAddr)->short2, ((Reg2Short*)&writeAddr)->short1, writing, (unsigned char*)data + writed);
|
||
}
|
||
writed += writing;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool GDevice::read_flash(unsigned int addr, void* data, int size)
|
||
{
|
||
unsigned int readAddr = addr;
|
||
int readed = 0;
|
||
int reading = 0;
|
||
while (readed < size) {
|
||
reading = min(crtlBufferSize, size - readed);
|
||
readAddr = addr + readed;
|
||
{
|
||
std::lock_guard<std::mutex> lck(m_mtxCtrl);
|
||
m_usb->control_msg(from_device, flash_access, ((Reg2Short*)&readAddr)->short2, ((Reg2Short*)&readAddr)->short1, reading, (unsigned char*)data + readed);
|
||
}
|
||
readed += reading;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
const int int_buffer_size = 1024;
|
||
int index_count = 0;
|
||
static void write_log(std::string fullname, std::string log)
|
||
{
|
||
std::string savepath;
|
||
savepath = fullname;
|
||
std::ofstream ofs(savepath, std::ios::app);
|
||
|
||
SYSTEMTIME sys;
|
||
GetLocalTime(&sys);
|
||
ofs << sys.wYear << "/" << sys.wMonth << "/" << sys.wDay << " " << sys.wHour << ":" << sys.wMinute << ":" << sys.wSecond << ":" << sys.wMilliseconds << " " << log << std::endl;
|
||
}
|
||
int image_index_c = 0;
|
||
void GDevice::recv_main()
|
||
{
|
||
const double timeout_ratio = (1000.0 / (15.0 * 1024 * 1024)); //!< s / Mbyte
|
||
int image_index = 0;
|
||
int buffer_size = 0;
|
||
int b_buffer_size = 0;
|
||
int f_buffer_size = 0;
|
||
unsigned char* bbuf = 0;
|
||
unsigned char* fbuf = 0;
|
||
unsigned char* buf;
|
||
int buffer_reading = 0;
|
||
int buffer_readed = 0;
|
||
const int read_timeout = 5000;
|
||
std::vector<unsigned char> image_data;
|
||
StopWatch sw;
|
||
while (m_bScan) {
|
||
image_index = image_indexs.Take();
|
||
if (!image_indexs.IsShutDown() && image_index >= 0)
|
||
{
|
||
buffer_reading = 0;
|
||
buffer_readed = 0;
|
||
buffer_size = frame_size(image_index);
|
||
image_data.resize(buffer_size * 2 + int_buffer_size);
|
||
buf = image_data.data() + int_buffer_size;
|
||
|
||
sw.reset();
|
||
while (sw.elapsed_ms() < read_timeout) {
|
||
while (DataOn() && sw.elapsed_ms() < read_timeout);
|
||
read_frame(image_index, buffer_readed);
|
||
buffer_reading = max(0, buffer_size - buffer_readed);
|
||
buffer_reading = read_data(buf + buffer_readed, buffer_reading, (int)(buffer_reading * timeout_ratio));
|
||
if (buffer_reading > 0)
|
||
buffer_readed += buffer_reading;
|
||
|
||
if (buffer_readed >= buffer_size) {
|
||
write_log("d:\\1.txt", std::to_string(image_index_c) + " time1 = " + std::to_string(sw.elapsed_ms()));
|
||
break;
|
||
}
|
||
}
|
||
|
||
image_index_c++;
|
||
if (buffer_readed != buffer_size)
|
||
{
|
||
write_log("d:\\1.txt", std::to_string(image_index_c) + " error readed:" + std::to_string(buffer_readed) + " per read:" + std::to_string(buffer_size) + " time = " + std::to_string(sw.elapsed_ms()));
|
||
}
|
||
else {
|
||
write_log("d:\\1.txt", std::to_string(image_index_c) + " get" + " time = " + std::to_string(sw.elapsed_ms()));
|
||
}
|
||
|
||
b_buffer_size = 0;
|
||
f_buffer_size = 0;
|
||
bbuf = buf - int_buffer_size;
|
||
fbuf = buf + buffer_size;
|
||
for (int i = 0; i < (buffer_size / int_buffer_size); i++)
|
||
{
|
||
if (buf[(i + 1) * int_buffer_size - 1] == 0)
|
||
{
|
||
memcpy(bbuf + b_buffer_size, buf + i * int_buffer_size, int_buffer_size - 1);
|
||
b_buffer_size += (int_buffer_size - 1);
|
||
}
|
||
else if (buf[(i + 1) * int_buffer_size - 1] == 255)
|
||
{
|
||
memcpy(fbuf + f_buffer_size, buf + i * int_buffer_size, int_buffer_size - 1);
|
||
f_buffer_size += (int_buffer_size - 1);
|
||
}
|
||
}
|
||
|
||
if (image_call)
|
||
{
|
||
if ((bbuf != NULL && b_buffer_size > 0)&&(fbuf != NULL && f_buffer_size > 0))
|
||
{
|
||
image_call(bbuf, b_buffer_size, fbuf, f_buffer_size, m_imagecall_userdata);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void GDevice::Int_main()
|
||
{
|
||
unsigned int int_buffer[4];
|
||
int size = 0;
|
||
while (m_bListen) {
|
||
size = m_usb->read_int(int_buffer, sizeof(int_buffer));
|
||
if (size >= 16)
|
||
{
|
||
if (int_buffer[2] != 0)
|
||
{
|
||
image_indexs.Put(int_buffer[1]);
|
||
}
|
||
MotorStatus* ms = (MotorStatus*)int_buffer;
|
||
|
||
//int ret = get_option(Cam_Options::scanner_scan_status);
|
||
//XdPrint("scanner_scan_status %d \n",ret);
|
||
//if (!ret)//<2F><><EFBFBD><EFBFBD><EFBFBD>幤<EFBFBD><E5B9A4><EFBFBD><EFBFBD>
|
||
//{
|
||
// XdPrint("scanner stoped 1\n");
|
||
// ((GScan200*)m_eventcall_userdata)->set_scan_status(false);//ֹͣ<CDA3><D6B9><EFBFBD>쳣ֹͣʱ<D6B9><CAB1>֪ͨͼ<D6AA><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣ
|
||
// m_run = false;
|
||
// XdPrint("scanner stoped 2\n");
|
||
//}
|
||
//else
|
||
//{
|
||
// XdPrint("scanner is scanning \n");
|
||
//}
|
||
//if (ms->value && 0x7fe) {
|
||
// if(m_eventcall_userdata){
|
||
//
|
||
// }
|
||
|
||
//}
|
||
if (event_call)
|
||
{
|
||
//0x3fe ==>b 1111 1111 10 <20>쳣λ<ECB3A3><CEBB><EFBFBD><EFBFBD>Чʱ
|
||
if (ms->value & 0x3fe) {
|
||
//((GScan200*)m_eventcall_userdata)->set_scan_status(false);
|
||
event_call(ms->value, m_eventcall_userdata);
|
||
m_run = false;
|
||
}
|
||
}
|
||
}
|
||
int ret = get_option(Cam_Options::scanner_scan_status);
|
||
if (m_run&&!ret)//<2F><><EFBFBD><EFBFBD><EFBFBD>幤<EFBFBD><E5B9A4><EFBFBD><EFBFBD>
|
||
{
|
||
//((GScan200*)m_eventcall_userdata)->set_scan_status(false);//ֹͣ<CDA3><D6B9><EFBFBD>쳣ֹͣʱ<D6B9><CAB1>֪ͨͼ<D6AA><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣ
|
||
m_run = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
void GDevice::init_cam()
|
||
{
|
||
}
|
||
|
||
int GDevice::read_data(void* data, int length, int timeout)
|
||
{
|
||
int readed = 0;
|
||
int reading = 0;
|
||
StopWatch sw;
|
||
while (readed < length && sw.elapsed_ms() < timeout) {
|
||
reading = max(0, min(length - readed, buffer_size));
|
||
reading = m_usb->read_bulk((unsigned char*)data + readed, reading);
|
||
if (reading > 0) {
|
||
readed += reading;
|
||
}
|
||
}
|
||
return readed;
|
||
}
|
||
|
||
void GDevice::read_frame(int index, int offset)
|
||
{
|
||
write_reg(3, index, offset);
|
||
}
|
||
|
||
int GDevice::frame_size(int index)
|
||
{
|
||
return read_reg(3, index);
|
||
}
|
||
|
||
int GDevice::read_reg(int type, int addr)
|
||
{
|
||
int value;
|
||
std::lock_guard<std::mutex> lck(m_mtxCtrl);
|
||
m_usb->control_msg(from_device, regs_access, type, addr, sizeof(value), &value);
|
||
return value;
|
||
}
|
||
|
||
|
||
void GDevice::write_reg(int type, int addr, int value)
|
||
{
|
||
std::lock_guard<std::mutex> lck(m_mtxCtrl);
|
||
m_usb->control_msg(to_device, regs_access, type, addr, sizeof(value), &value);
|
||
}
|
||
|
||
void GDevice::set_option(Cam_Options option, unsigned int value)
|
||
{
|
||
unsigned int val = 0;
|
||
switch (option)
|
||
{
|
||
case scanner_config:
|
||
write_reg(USERDEFINE, ModeParam, value);
|
||
break;
|
||
case scanner_scan_skrew:
|
||
val = read_reg(MOTOR_BOARD, 0x00);
|
||
((MotorSetting*)& val)->skew_enable = value;
|
||
write_reg(MOTOR_BOARD, 0x00, val);
|
||
break;
|
||
case scanner_stample_enable:
|
||
val = read_reg(MOTOR_BOARD, 0x00);
|
||
((MotorSetting*)& val)->staple_enable = value;
|
||
write_reg(MOTOR_BOARD, 0x00, val);
|
||
break;
|
||
case scanner_doublePape_enable:
|
||
val = read_reg(MOTOR_BOARD, 0x00);
|
||
((MotorSetting*)& val)->double_paper = value;
|
||
write_reg(MOTOR_BOARD, 0x00, val);
|
||
break;
|
||
case scanner_stop_motor:
|
||
val = read_reg(MOTOR_BOARD, 0x00);
|
||
((MotorSetting*)& val)->scan_enable = value;
|
||
write_reg(MOTOR_BOARD, 0x00, val);
|
||
break;
|
||
case scanner_error_clean:
|
||
val = read_reg(MOTOR_BOARD, 0x00);
|
||
((MotorSetting*)& val)->error_clean = value;
|
||
write_reg(MOTOR_BOARD, 0x00, val);
|
||
break;
|
||
case scanner_Init_Status:
|
||
val = read_reg(MOTOR_BOARD, 0x00);
|
||
((MotorSetting*)& val)->status_init = value;
|
||
write_reg(MOTOR_BOARD, 0x00, val);
|
||
break;
|
||
case scanner_IIC_Config:
|
||
val = read_reg(MOTOR_BOARD, 0x00);
|
||
((MotorSetting*)& val)->iic_config = value;
|
||
write_reg(MOTOR_BOARD, 0x00, val);
|
||
break;
|
||
case scanner_Speed_Config:
|
||
val = read_reg(MOTOR_BOARD, 0x00);
|
||
((MotorSetting*)& val)->speed_set_enable = value;
|
||
write_reg(MOTOR_BOARD, 0x00, val);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
int GDevice::get_option(Cam_Options option)
|
||
{
|
||
int value = 0;
|
||
switch (option)
|
||
{
|
||
case scanner_cover_status:
|
||
value = read_reg(1, 0x01);
|
||
value = ((MotorStatus*)& value)->open_machine;
|
||
break;
|
||
case scanner_pick_paper_stauts:
|
||
value = read_reg(1, 0x01);
|
||
value = ((MotorStatus*)& value)->pick_failed;
|
||
break;
|
||
case scanner_jam_stauts:
|
||
value = read_reg(1, 0x01);
|
||
value = ((MotorStatus*)& value)->stop_jam;
|
||
break;
|
||
case scanner_paper_count:
|
||
value = read_reg(1, 0x02);
|
||
value = ((MotorMode*)& value)->scan_num;
|
||
break;
|
||
case scanner_double_paper:
|
||
value = read_reg(1, 0x01);
|
||
value= ((MotorStatus*)& value)->double_paper;
|
||
break;
|
||
case scanner_staple_state:
|
||
value = read_reg(1, 0x01);
|
||
value = ((MotorStatus*)& value)->staple;
|
||
break;
|
||
case scanner_skrew_state:
|
||
value = read_reg(1, 0x01);
|
||
value = ((MotorStatus*)& value)->papertilted;
|
||
break;
|
||
case scanner_paper_have:
|
||
value = read_reg(MOTOR_BOARD, 0x02);
|
||
value = ((Motor_Mode*)& value)->feeding_paper_ready;
|
||
break;
|
||
case scanner_scan_status:
|
||
value = read_reg(MOTOR_BOARD, 0x02);
|
||
value = ((Motor_Mode*)& value)->scan_status;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return value;
|
||
}
|
||
|
||
std::vector<Cam_Options> GDevice::support_options()
|
||
{
|
||
std::set<Cam_Options> options;
|
||
options.insert(Cam_Options::scanner_exposure_blue);
|
||
options.insert(Cam_Options::scanner_exposure_gray);
|
||
options.insert(Cam_Options::scanner_exposure_red);
|
||
|
||
return std::vector<Cam_Options>(options.begin(), options.end());
|
||
}
|
||
|
||
void GDevice::pick_paper(void)
|
||
{
|
||
MotorSetting ms;
|
||
ms.value = read_reg(MOTOR_BOARD, 0x00);
|
||
ms.pick_paper = 0;
|
||
write_reg(MOTOR_BOARD, 0x00, ms.value);
|
||
ms.pick_paper = 1;
|
||
write_reg(MOTOR_BOARD, 0x00, ms.value);
|
||
}
|
||
|
||
void GDevice::trigger_scan(void)
|
||
{
|
||
ScanTriger st;
|
||
st.value = 0;
|
||
write_reg(MAIN_BOARD, 0x02, st.value);
|
||
st.triger = 1;
|
||
write_reg(MAIN_BOARD, 0x02, st.value);
|
||
}
|
||
|
||
bool GDevice::DataOn()
|
||
{
|
||
return read_reg(USERDEFINE, IMAGEREGS);
|
||
}
|