#include "stdafx.h" #include "GDevice.h" #include "IUsb.h" #include #include #include #include #include #include #include #include #include "StopWatch.h" #include "device_common.h" #include "GScan200.h" #ifndef WIN32 #include #endif #include #define DSP_CODE_ADDR 0 #define USER_ADDR 0x4000 using namespace std; //class GScan200; GDevice::GDevice(std::shared_ptr 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(new std::thread(&GDevice::Int_main, this)); m_threadrecv = std::shared_ptr(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 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 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 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)//电机板工作中 //{ // XdPrint("scanner stoped 1\n"); // ((GScan200*)m_eventcall_userdata)->set_scan_status(false);//停止或异常停止时,通知图像处理线程扫描仪已停止 // 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 异常位高有效时 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)//电机板工作中 { //((GScan200*)m_eventcall_userdata)->set_scan_status(false);//停止或异常停止时,通知图像处理线程扫描仪已停止 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 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 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 GDevice::support_options() { std::set 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(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); }