/* * Osciloscope.cpp * * Created on: 14 но¤б. 2016 г. * Author: titov */ #include "Osciloscope.hh" #include using peripheral::IMemoryAccess; using driver::Osciloscope; Osciloscope::Osciloscope( IMemoryAccess & rf_memory ) : memory(rf_memory), data_length( rf_memory.getCapacity() / value_size ) {} bool Osciloscope::configurate( const Configuration & config ) { if( income_parameters_valid(config) ) { for(unsigned int i = 0; i < config.num_parameter; i++) { if(config.parameter[i]) parameter[i] = config.parameter[i]; else return false; } condition = config.condition == 0 ? LessEqual : config.condition == 1 ? GreatEqual : Equal; threshold = config.threshold; num_parameter = config.num_parameter; trigger = config.trigger; save_sample_period = static_cast( (config.measurement_period / sample_time) ); measurement_num = data_length / num_parameter; measurement_after_trigger = 1 + static_cast( measurement_num * ( config.after_trigger_percent * 0.01f ) ); if(measurement_after_trigger > measurement_num) measurement_after_trigger = measurement_num; configured = true; flyover_bound = false; return true; } return false; } bool Osciloscope::income_parameters_valid(const Configuration& cfg) { using namespace std; //Поэтапная проверка переданных параметров. bool p1_val = parameter_in_bound( 0u, cfg.num_parameter, max_num_parameter ); bool p2_val = cfg.trigger; bool p3_val = parameter_in_bound( 0.0f, cfg.after_trigger_percent, 100.0f ); bool p4_val = parameter_in_bound( 0.0f, cfg.measurement_period, 100.0f ); bool p5_val = not isnan( cfg.threshold ); //Формирование признака валидности параметров. bool valid = p1_val && p2_val && p3_val && p4_val && p5_val; return valid; } template bool Osciloscope::parameter_in_bound(T l_bound, T value, T r_bound) const { return (r_bound >= value && value >= l_bound); } Osciloscope::State Osciloscope::getState() const { std::size_t meas_count = flyover_bound ? measurement_num : start_measurement_index; //??? return { meas_count, num_parameter, measurement_after_trigger, sample_time * save_sample_period, measurement_active, triggered }; } void driver::Osciloscope::setSampleTime(float ts_in_second) { sample_time = ts_in_second; } void Osciloscope::parameters_registration() { if(++sample_cnt >= save_sample_period) { sample_cnt = 0; if( !triggered ) { switch( condition ) { case LessEqual: { triggered = *trigger <= threshold;} break; case GreatEqual: { triggered = *trigger >= threshold;} break; case Equal: { triggered = *trigger == threshold;} break; default: { triggered = true; } break; } } unsigned long current_offset = num_parameter * measurement_index; value_type actual_parameter[max_num_parameter]; for(unsigned int i = 0; i < num_parameter; i++) { actual_parameter[i] = *parameter[i]; } memory.write( reinterpret_cast(actual_parameter), current_offset * value_size, num_parameter * value_size); if( ++measurement_index >= measurement_num ) { measurement_index = 0; flyover_bound = true; } if( triggered && --cnt_after_trigger <= 0 ) { start_measurement_index = measurement_index; stop(); } } } bool Osciloscope::isDataReady() const { return !measurement_active && triggered; } float Osciloscope::getMeasurement( unsigned int id, unsigned long index ) const { value_type result = NAN; if( !measurement_active ) { std::size_t temporal_idx = flyover_bound ? ( index + start_measurement_index ) : index; if( temporal_idx >= measurement_num ) temporal_idx -= measurement_num; std::size_t value_index = temporal_idx * num_parameter + id; memory.read( reinterpret_cast( &result ), value_index * value_size, value_size ); } return result; } void Osciloscope::start() { if( configured ) { cnt_after_trigger = measurement_after_trigger; sample_cnt = save_sample_period; triggered = false; measurement_active = true; measurement_index = 0; //proc_ctrl->enable(); } } void Osciloscope::stop() { measurement_active = false; configured = false; //proc_ctrl->disable(); } void Osciloscope::process() { if(measurement_active) { parameters_registration(); } }