twain3.0/huagao/Device/GDevice.cpp

546 lines
13 KiB
C++
Raw Normal View History

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