MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/driver/Scope.cpp
2024-06-07 11:12:56 +03:00

350 lines
7.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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;
}