add start scan flow
This commit is contained in:
parent
96ecacb861
commit
be23610bae
|
@ -321,6 +321,7 @@ void FpgaComm::setDelayTime(int value) {
|
||||||
|
|
||||||
void FpgaComm::update()
|
void FpgaComm::update()
|
||||||
{
|
{
|
||||||
|
// spends 6.5s
|
||||||
for(int i = 0; i < MAX_REGS; i++)
|
for(int i = 0; i < MAX_REGS; i++)
|
||||||
{
|
{
|
||||||
read(i, fpgaParams.regs[i]);
|
read(i, fpgaParams.regs[i]);
|
||||||
|
|
|
@ -158,6 +158,10 @@ int gVideo::add_v4l2_memory(int ind)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
int gVideo::get_mem_count(void)
|
||||||
|
{
|
||||||
|
return n_buffers;
|
||||||
|
}
|
||||||
|
|
||||||
void gVideo::set_size(int width,int height){
|
void gVideo::set_size(int width,int height){
|
||||||
if(!buffers.empty())
|
if(!buffers.empty())
|
||||||
|
|
|
@ -21,6 +21,7 @@ public:
|
||||||
bool hasframe();
|
bool hasframe();
|
||||||
virtual void *read_frame(int timeout, size_t& size, int& ind); // call add_v4l2_memory to put the buffer into the V4L2 queue again
|
virtual void *read_frame(int timeout, size_t& size, int& ind); // call add_v4l2_memory to put the buffer into the V4L2 queue again
|
||||||
int add_v4l2_memory(int ind);
|
int add_v4l2_memory(int ind);
|
||||||
|
int get_mem_count(void);
|
||||||
void set_size(int width, int height);
|
void set_size(int width, int height);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -248,20 +248,31 @@ void scanner_hw::init(void)
|
||||||
}
|
}
|
||||||
void scanner_hw::thread_image_capture(void)
|
void scanner_hw::thread_image_capture(void)
|
||||||
{
|
{
|
||||||
PACKIMAGE img;
|
PACKIMAGE img;
|
||||||
|
safe_fifo<int> avail_mem("v4l2-mem");
|
||||||
|
int used_v4l2_mem = 0;
|
||||||
|
auto put_v4l2_mem = [&](BEFORE_DESTROY_PARAM) -> BEFORE_DESTROY_RET
|
||||||
|
{
|
||||||
|
int ind = (int)(long)param;
|
||||||
|
|
||||||
|
mem->detach(nullptr);
|
||||||
|
avail_mem.save(ind);
|
||||||
|
};
|
||||||
|
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "scanning thread working ...\n");
|
||||||
memset(&img, 0, sizeof(img));
|
memset(&img, 0, sizeof(img));
|
||||||
do
|
while(1) // auto scan cycle ...
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
int ind = -1;
|
int ind = -1;
|
||||||
void* frame = camera_->read_frame(1000, size, ind);
|
void* frame = camera_->read_frame(1000, size, ind);
|
||||||
|
|
||||||
|
// scanning ONE turn ...
|
||||||
while(frame)
|
while(frame)
|
||||||
{
|
{
|
||||||
dyn_mem_ptr mem = dyn_mem::memory(size);
|
dyn_mem_shared_ptr mem = new dyn_mem_shared(frame, size, put_v4l2_mem, (void*)ind);
|
||||||
|
|
||||||
camera_->add_v4l2_memory(ind);
|
used_v4l2_mem++;
|
||||||
img.pos.paper_ind++;
|
img.pos.paper_ind++;
|
||||||
img.pos.status = IMG_STATUS_OK;
|
img.pos.status = IMG_STATUS_OK;
|
||||||
img_handler_(mem, true, &img);
|
img_handler_(mem, true, &img);
|
||||||
|
@ -269,16 +280,78 @@ void scanner_hw::thread_image_capture(void)
|
||||||
if(img.pos.paper_ind == scan_count_ || is_scan_fatal())
|
if(img.pos.paper_ind == scan_count_ || is_scan_fatal())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// retrieve V4L2 memory ...
|
||||||
|
retrieve_v4l2_mem(&avail_mem, &used_v4l2_mem);
|
||||||
|
if(used_v4l2_mem >= camera_->get_mem_count())
|
||||||
|
{
|
||||||
|
stop_scan();
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "Scanning stopped for that V4L2 is out of memory!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
motor_->pick_paper();
|
motor_->pick_paper();
|
||||||
frame = camera_->read_frame(1000, size, ind);
|
frame = camera_->read_frame(1000, size, ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
}while(auto_scan_);
|
// retrieve v4l2-mem ...
|
||||||
|
while(avail_mem.take(ind, false))
|
||||||
|
{
|
||||||
|
used_v4l2_mem--;
|
||||||
|
camera_->add_v4l2_memory(ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!auto_scan_)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// wait paper ...
|
||||||
|
}
|
||||||
|
|
||||||
|
int times = 0;
|
||||||
|
while(used_v4l2_mem)
|
||||||
|
{
|
||||||
|
if(times++ == 0)
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "Wait to retrieve %d V4L2 memory(s) ...\n", used_v4l2_mem);
|
||||||
|
else if(times >= 1000)
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "Wait %d times, but %d V4L2 memory(s) has not returned yet!\n", times, used_v4l2_mem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
retrieve_v4l2_mem(&avail_mem, &used_v4l2_mem);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
}
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "scanning thread exited.\n");
|
||||||
}
|
}
|
||||||
bool scanner_hw::is_scan_fatal(void)
|
bool scanner_hw::is_scan_fatal(void)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
void scanner_hw::retrieve_v4l2_mem(safe_fifo<int>* mem, int* used)
|
||||||
|
{
|
||||||
|
int u = *used,
|
||||||
|
ind = 0;
|
||||||
|
|
||||||
|
while(u >= camera_->get_mem_count())
|
||||||
|
{
|
||||||
|
if(mem->size())
|
||||||
|
{
|
||||||
|
if(ind)
|
||||||
|
utils::to_log(LOG_LEVEL_WARNING, "V4L2 memory returned.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(ind == 0)
|
||||||
|
utils::to_log(LOG_LEVEL_WARNING, "V4L2 is out of memory, wait image processor return ...\n");
|
||||||
|
|
||||||
|
if(ind++ > 1000) // 3 seconds ...
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||||||
|
}
|
||||||
|
while(mem->take(ind, false))
|
||||||
|
{
|
||||||
|
u--;
|
||||||
|
camera_->add_v4l2_memory(ind);
|
||||||
|
}
|
||||||
|
*used = u;
|
||||||
|
}
|
||||||
|
|
||||||
// sane_opt_provider
|
// sane_opt_provider
|
||||||
char* scanner_hw::get_value(const char* name, void* value, size_t* size, int* err)
|
char* scanner_hw::get_value(const char* name, void* value, size_t* size, int* err)
|
||||||
|
@ -392,12 +465,28 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
|
||||||
}
|
}
|
||||||
int scanner_hw::start_scan(void)
|
int scanner_hw::start_scan(void)
|
||||||
{
|
{
|
||||||
|
unsigned int val = 0;
|
||||||
|
|
||||||
if(!camera_.get() || !motor_.get() || !img_controller_.get())
|
if(!camera_.get() || !motor_.get() || !img_controller_.get())
|
||||||
return SCANNER_ERR_DEVICE_NOT_READY;
|
return DEV_ERR(NOT_READY);
|
||||||
|
|
||||||
motor_->clear_error();
|
motor_->clear_error();
|
||||||
if(!motor_->paper_ready() && !auto_scan_)
|
if(!motor_->read(PORT_STATUS, val))
|
||||||
return SCANNER_ERR_DEVICE_NO_PAPER;
|
return DEV_ERR(GET_STATUS_FAILED);
|
||||||
|
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "start scan: status = 0x%08x.\n", val);
|
||||||
|
if (((SMBSTATUS*)&val)->open_machine) // 0x700fe
|
||||||
|
return DEV_ERR(COVER_OPENNED);
|
||||||
|
|
||||||
|
if(!motor_->read(PORT_MODE, val))
|
||||||
|
return DEV_ERR(GET_STATUS_FAILED);
|
||||||
|
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "start scan: mode-status = 0x%08x.\n", val);
|
||||||
|
if(val & 0x1c0000)
|
||||||
|
return DEV_ERR(PAPER_JAMMED);
|
||||||
|
|
||||||
|
if(((SMBMODE*)&val)->feeding_paper_ready == 0 && !auto_scan_)
|
||||||
|
return DEV_ERR(NO_PAPER);
|
||||||
|
|
||||||
camera_->start();
|
camera_->start();
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ class scanner_hw : public sane_opt_provider
|
||||||
void init(void);
|
void init(void);
|
||||||
void thread_image_capture(void);
|
void thread_image_capture(void);
|
||||||
bool is_scan_fatal(void);
|
bool is_scan_fatal(void);
|
||||||
|
void retrieve_v4l2_mem(safe_fifo<int>* mem, int* used);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
scanner_hw();
|
scanner_hw();
|
||||||
|
@ -556,4 +557,4 @@ public:
|
||||||
// },
|
// },
|
||||||
// "depend": "is-check-askew==true"
|
// "depend": "is-check-askew==true"
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -427,6 +427,10 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p
|
||||||
scan_err_ = cis_->open(receiver);
|
scan_err_ = cis_->open(receiver);
|
||||||
if(scan_err_ == 0)
|
if(scan_err_ == 0)
|
||||||
scan_err_ = cis_->start_scan();
|
scan_err_ = cis_->start_scan();
|
||||||
|
if(scan_err_)
|
||||||
|
{
|
||||||
|
cis_->stop_scan();
|
||||||
|
}
|
||||||
BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, scan_err_);
|
BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, scan_err_);
|
||||||
*used |= INT32_MAX + 1;
|
*used |= INT32_MAX + 1;
|
||||||
|
|
||||||
|
|
|
@ -322,22 +322,28 @@ data_source::~data_source()
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// dyn_mem
|
// dyn_mem
|
||||||
|
#ifdef STAT_MEM
|
||||||
uint64_t dyn_mem::mem_used_bytes_ = 0;
|
uint64_t dyn_mem::mem_used_bytes_ = 0;
|
||||||
MUTEX dyn_mem::mem_lock_;
|
MUTEX dyn_mem::mem_lock_;
|
||||||
|
#endif
|
||||||
|
|
||||||
dyn_mem::dyn_mem(size_t size) : buf_(nullptr), len_(0), space_(ALIGN_TO(size, 16))
|
dyn_mem::dyn_mem(size_t size) : buf_(nullptr), len_(0), space_(ALIGN_TO(size, 16))
|
||||||
{
|
{
|
||||||
buf_ = (uint8_t*)malloc(space_);
|
buf_ = (uint8_t*)malloc(space_);
|
||||||
if (buf_)
|
if (buf_)
|
||||||
{
|
{
|
||||||
SIMPLE_LOCK(dyn_mem::mem_lock_);
|
#ifdef STAT_MEM
|
||||||
dyn_mem::mem_used_bytes_ += space_;
|
{
|
||||||
|
SIMPLE_LOCK(dyn_mem::mem_lock_);
|
||||||
|
dyn_mem::mem_used_bytes_ += space_;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
memset(buf_, 0, space_);
|
memset(buf_, 0, space_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dyn_mem::dyn_mem(void* buf, size_t size) : buf_((uint8_t*)buf), space_(size), len_(size)
|
dyn_mem::dyn_mem(void* buf, size_t size)
|
||||||
|
: buf_((uint8_t*)buf), space_(size), len_(size)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dyn_mem::~dyn_mem()
|
dyn_mem::~dyn_mem()
|
||||||
|
@ -345,17 +351,22 @@ dyn_mem::~dyn_mem()
|
||||||
if (buf_)
|
if (buf_)
|
||||||
{
|
{
|
||||||
free(buf_);
|
free(buf_);
|
||||||
|
#ifdef STAT_MEM
|
||||||
{
|
{
|
||||||
SIMPLE_LOCK(dyn_mem::mem_lock_);
|
SIMPLE_LOCK(dyn_mem::mem_lock_);
|
||||||
dyn_mem::mem_used_bytes_ -= space_;
|
dyn_mem::mem_used_bytes_ -= space_;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef STAT_MEM
|
||||||
uint64_t dyn_mem::mem_used(void)
|
uint64_t dyn_mem::mem_used(void)
|
||||||
{
|
{
|
||||||
return dyn_mem::mem_used_bytes_;
|
return dyn_mem::mem_used_bytes_;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
dyn_mem_ptr dyn_mem::memory(size_t size)
|
dyn_mem_ptr dyn_mem::memory(size_t size)
|
||||||
{
|
{
|
||||||
return new dyn_mem(size);
|
return new dyn_mem(size);
|
||||||
|
@ -424,10 +435,12 @@ dyn_mem& dyn_mem::operator+=(dyn_mem& r)
|
||||||
memcpy(buf, buf_, len_);
|
memcpy(buf, buf_, len_);
|
||||||
free(buf_);
|
free(buf_);
|
||||||
buf_ = buf;
|
buf_ = buf;
|
||||||
|
#ifdef STAT_MEM
|
||||||
{
|
{
|
||||||
SIMPLE_LOCK(dyn_mem::mem_lock_);
|
SIMPLE_LOCK(dyn_mem::mem_lock_);
|
||||||
dyn_mem::mem_used_bytes_ += size - space_;
|
dyn_mem::mem_used_bytes_ += size - space_;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
space_ = size;
|
space_ = size;
|
||||||
}
|
}
|
||||||
memcpy(buf_ + len_, r.buf_, r.get_rest());
|
memcpy(buf_ + len_, r.buf_, r.get_rest());
|
||||||
|
@ -475,6 +488,17 @@ int dyn_mem::fetch_data(void* buf, uint32_t* size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
dyn_mem_shared::dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy, void* param)
|
||||||
|
: dyn_mem(buf, size), destroy_(destroy), param_(param)
|
||||||
|
{}
|
||||||
|
dyn_mem_shared::~dyn_mem_shared()
|
||||||
|
{
|
||||||
|
if(destroy_)
|
||||||
|
destroy_(this, param_);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
file_reader::file_reader() : len_(0), src_(nullptr), path_(""), consume_(0)
|
file_reader::file_reader() : len_(0), src_(nullptr), path_(""), consume_(0)
|
||||||
|
|
|
@ -205,6 +205,10 @@ public:
|
||||||
virtual int fetch_data(void* buf, uint32_t* size) = 0;
|
virtual int fetch_data(void* buf, uint32_t* size) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #define STAT_MEM
|
||||||
|
#define BEFORE_DESTROY_RET void
|
||||||
|
#define BEFORE_DESTROY_PARAM dyn_mem* mem, void* param
|
||||||
|
#define BEFORE_DESTROY_FUNC std::function<BEFORE_DESTROY_RET(BEFORE_DESTROY_PARAM)>
|
||||||
|
|
||||||
class dyn_mem : public data_source
|
class dyn_mem : public data_source
|
||||||
{
|
{
|
||||||
|
@ -212,18 +216,22 @@ class dyn_mem : public data_source
|
||||||
size_t space_; // occupy space in bytes
|
size_t space_; // occupy space in bytes
|
||||||
size_t len_; // data length in bytes
|
size_t len_; // data length in bytes
|
||||||
|
|
||||||
|
#ifdef STAT_MEM
|
||||||
static MUTEX mem_lock_;
|
static MUTEX mem_lock_;
|
||||||
static uint64_t mem_used_bytes_;
|
static uint64_t mem_used_bytes_;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dyn_mem(size_t size);
|
dyn_mem(size_t size);
|
||||||
dyn_mem(void* buf, size_t size);
|
dyn_mem(void* buf, size_t size);
|
||||||
|
|
||||||
|
#ifdef STAT_MEM
|
||||||
static uint64_t mem_used(void);
|
static uint64_t mem_used(void);
|
||||||
|
#endif
|
||||||
static dyn_mem* memory(size_t size);
|
static dyn_mem* memory(size_t size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~dyn_mem();
|
virtual ~dyn_mem();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint32_t space(void);
|
uint32_t space(void);
|
||||||
|
@ -246,6 +254,17 @@ public:
|
||||||
// following API valid when is_memory_block() return false
|
// following API valid when is_memory_block() return false
|
||||||
virtual int fetch_data(void* buf, uint32_t* size) override;
|
virtual int fetch_data(void* buf, uint32_t* size) override;
|
||||||
};
|
};
|
||||||
|
class dyn_mem_shared : public dyn_mem
|
||||||
|
{
|
||||||
|
BEFORE_DESTROY_FUNC destroy_ = BEFORE_DESTROY_FUNC();
|
||||||
|
void* param_ = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy = BEFORE_DESTROY_FUNC(), void* param = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~dyn_mem_shared();
|
||||||
|
};
|
||||||
|
|
||||||
class file_reader : public data_source
|
class file_reader : public data_source
|
||||||
{
|
{
|
||||||
|
@ -284,6 +303,7 @@ CLS_PTR(data_holder);
|
||||||
CLS_PTR(mem_holder);
|
CLS_PTR(mem_holder);
|
||||||
CLS_PTR(data_source);
|
CLS_PTR(data_source);
|
||||||
CLS_PTR(dyn_mem);
|
CLS_PTR(dyn_mem);
|
||||||
|
CLS_PTR(dyn_mem_shared);
|
||||||
CLS_PTR(file_reader);
|
CLS_PTR(file_reader);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#define RETURN_DESC_IF(var, hgerr) \
|
#define RETURN_DESC_IF(var, hgerr) \
|
||||||
if(var == hgerr) \
|
if(var == hgerr) \
|
||||||
return from_default_language(STATU_DESC_##hgerr);
|
return from_default_language(STATU_DESC_##hgerr);
|
||||||
|
#define DEV_ERR(err) \
|
||||||
|
SCANNER_ERR_DEVICE_##err
|
||||||
|
|
||||||
enum scanner_err
|
enum scanner_err
|
||||||
{
|
{
|
||||||
|
@ -77,6 +79,7 @@ enum scanner_err
|
||||||
SCANNER_ERR_DEVICE_UNKNOWN_STATUS, // 设备处于未知状态
|
SCANNER_ERR_DEVICE_UNKNOWN_STATUS, // 设备处于未知状态
|
||||||
|
|
||||||
SCANNER_ERR_DEVICE_NOT_READY, // 设备未准备好(执行某操作的前置条件未准备好)
|
SCANNER_ERR_DEVICE_NOT_READY, // 设备未准备好(执行某操作的前置条件未准备好)
|
||||||
|
SCANNER_ERR_DEVICE_GET_STATUS_FAILED, // 获取电机板状态失败
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -59,8 +59,8 @@ add_packagedirs("sdk")
|
||||||
|
|
||||||
add_defines("VER_MAIN=2")
|
add_defines("VER_MAIN=2")
|
||||||
add_defines("VER_FAMILY=300")
|
add_defines("VER_FAMILY=300")
|
||||||
add_defines("VER_DATE=20231229")
|
add_defines("VER_DATE=20240103")
|
||||||
add_defines("VER_BUILD=12")
|
add_defines("VER_BUILD=7")
|
||||||
|
|
||||||
target("conf")
|
target("conf")
|
||||||
set_kind("phony")
|
set_kind("phony")
|
||||||
|
|
Loading…
Reference in New Issue