MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/driver/Scope.cpp

350 lines
7.4 KiB
C++

/*
* Scope.cpp
*
* Created on: 27 àïð. 2020 ã.
* Author: LeonidTitov
*/
#include "Scope.hh"
#include <algorithm>
bool driver::Scope::setup(Frame * new_frame, systemic::IValue<bool> * new_trigger,
TriggerMode mode, Times times_to_on, Time time_before,
Time time_after ) {
if( mode == Cyclic or mode == Repeat )
if( time_before != 0.0f )
return false;
if( not new_frame or not new_trigger )
return false;
trigger.stop();
capture.stop();
std::size_t frame_size = new_frame->size();
buffer_constructor.destroy( buffer );
buffer_constructor.construct( buffer, memory, frame_size, put_cache, put_cache_size, get_cache, get_cache_size );
frame = new_frame;
FrameIndex before_fix_frames, after_fix_frames;
FrameIndex step = 0;
do {
data_quant = ++step * process_quant;
before_fix_frames = time_before / ( data_quant );
after_fix_frames = time_after / ( data_quant );
} while( before_fix_frames + after_fix_frames > buffer->capacity() );
capture.setup( before_fix_frames, after_fix_frames, step );
trigger.setup(new_trigger, times_to_on, mode == Repeat );
restart_on_done = mode == Cyclic;
return is_setupped = true;
}
void driver::Scope::reset() {
disable();
buffer->clear();
is_setupped = false;
}
bool driver::Scope::isSetup() const {
return is_setupped;
}
void driver::Scope::start() {
trigger.start();
capture.start();
}
void driver::Scope::stop() {
trigger.stop();
}
void driver::Scope::disable() {
trigger.stop();
capture.stop();
}
std::pair<driver::Scope::Times, driver::Scope::Times> driver::Scope::trigger_progress() const {
return trigger.progress();
}
std::pair<driver::Scope::FrameIndex, driver::Scope::FrameIndex> driver::Scope::data_progress() const {
return capture.progress();
}
std::pair<driver::Scope::FrameIndex, driver::Scope::FrameIndex> driver::Scope::data_info() const {
return { buffer->fixed( capture.head() ), capture.trigger_position };
}
driver::Scope::Time driver::Scope::sample_time() const {
return data_quant;
}
bool driver::Scope::isActive() const {
return capture.is_active();
}
bool driver::Scope::isTriggerFixed() const {
return trigger.is_fixed();
}
std::pair<const char *, std::size_t> driver::Scope::getFrame(
FrameIndex index ) {
return { buffer->get( capture.head().relative(index) ), buffer->get_frame_size() };
}
void driver::Scope::freeFrame( FrameIndex index ) {}
driver::Scope::Scope(peripheral::IMemoryAccess & memory_access,
std::pmr::memory_resource * initialization, std::size_t put_cache_size, std::size_t get_cache_size ) :
frame( nullptr ), memory(memory_access), buffer_constructor( initialization ),
buffer( buffer_constructor.allocate(1) ),
put_cache( reinterpret_cast<char *>( initialization->allocate( put_cache_size, 1 ) ) ), put_cache_size(put_cache_size),
get_cache( reinterpret_cast<char *>( initialization->allocate( put_cache_size, 1 ) ) ), get_cache_size(get_cache_size),
process_quant( 0.0f ), data_quant( 0.0f ),
is_setupped( false ), restart_on_done( false ),
trigger(), capture() {}
void driver::Scope::setSampleTime( float ts_in_second ) {
process_quant = ts_in_second;
}
void driver::Scope::process() {
if( trigger.at_fix() )
capture.fix( buffer->fixate( capture.desired_trigger() ) );
if( capture.at_shot() )
buffer->put( frame->data() );
if( capture.is_done() ) {
if( restart_on_done ) {
buffer->restart( capture.head() );
trigger.start();
capture.start();
}
}
}
void driver::Scope::TriggerManager::setup( Condition * new_condition, Times new_threshold,
bool repeatable ) {
condition = new_condition;
prev_condition = *condition;
enable = false;
counter = 0;
threshold = new_threshold;
fixed = false;
repeat_mode = repeatable;
}
bool driver::Scope::TriggerManager::at_fix() {
bool fix = false;
bool current_condition = *condition;
if( current_condition and enable ) {
if( counter < threshold ) {
if( not prev_condition )
counter++;
} else if( not fixed ) {
counter = 0;
fixed = not repeat_mode;
fix = true;
}
}
prev_condition = current_condition;
return fix;
}
void driver::Scope::TriggerManager::stop() {
enable = false;
}
bool driver::Scope::TriggerManager::is_fixed() const {
return fixed;
}
void driver::Scope::TriggerManager::start() {
counter = 0;
fixed = false;
enable = true;
}
driver::Scope::TriggerManager::TriggerManager() :
condition( default_condition() ), enable(false), repeat_mode(false),
counter(0), threshold(0), prev_condition(true), fixed(false) {}
void driver::Scope::CaptureManager::setup( FrameIndex before_fix_frames,
FrameIndex after_fix_frames,
FrameIndex step ) {
before_trigger = true;
step_counter = 0;
before_trigger_frame_threshold = before_fix_frames;
after_trigger_frame_threshold = after_fix_frames;
step_threshold = step;
}
void driver::Scope::CaptureManager::fix( std::pair<Index, std::size_t> info ) {
before_trigger = false;
//step_counter = step_threshold;
head_index = info.first;
trigger_position = before_trigger_frame_counter = info.second;
}
bool driver::Scope::CaptureManager::at_shot() {
bool shot = false;
if( active ) {
step_counter = std::min( step_counter + 1, step_threshold );
if( step_counter == step_threshold ) {
step_counter = 0;
if( before_trigger ) {
before_trigger_frame_counter = std::min( before_trigger_frame_counter + 1, before_trigger_frame_threshold );
} else {
after_trigger_frame_counter = std::min( after_trigger_frame_counter + 1, after_trigger_frame_threshold );
if( after_trigger_frame_counter == after_trigger_frame_threshold ) {
active = false;
}
}
shot = true;
}
}
return shot;
}
void driver::Scope::CaptureManager::start() {
before_trigger_frame_counter = 0;
after_trigger_frame_counter = 0;
step_counter = step_threshold;
active = true;
}
bool driver::Scope::CaptureManager::is_active() const {
return active;
}
bool driver::Scope::CaptureManager::is_done() const {
return after_trigger_frame_counter == after_trigger_frame_threshold;
}
driver::Scope::Index driver::Scope::CaptureManager::head() const {
return head_index;
}
driver::Scope::CaptureManager::CaptureManager() : active(false),
before_trigger_frame_counter(0), after_trigger_frame_counter(0),
before_trigger_frame_threshold(0), after_trigger_frame_threshold(0),
trigger_position(0),
step_counter(0), step_threshold(0),
before_trigger(0), head_index() {}
struct DefaultCondition : public driver::Scope::Condition {
operator bool() const { return false; }
};
driver::Scope::Condition * driver::Scope::TriggerManager::default_condition() {
static DefaultCondition condition;
return &condition;
}
void driver::Scope::CaptureManager::stop() {
active = false;
}