/* * Scope.cpp * * Created on: 27 апр. 2020 г. * Author: LeonidTitov */ #include "Scope.hh" #include bool driver::Scope::setup(Frame * new_frame, systemic::IValue * 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::trigger_progress() const { return trigger.progress(); } std::pair driver::Scope::data_progress() const { return capture.progress(); } std::pair 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 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( initialization->allocate( put_cache_size, 1 ) ) ), put_cache_size(put_cache_size), get_cache( reinterpret_cast( 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 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; }