198 lines
4.4 KiB
C++
198 lines
4.4 KiB
C++
/*
|
||
* Osciloscope.cpp
|
||
*
|
||
* Created on: 14 но¤б. 2016 г.
|
||
* Author: titov
|
||
*/
|
||
|
||
#include "Osciloscope.hh"
|
||
|
||
#include <cmath>
|
||
|
||
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<std::size_t>( (config.measurement_period / sample_time) );
|
||
|
||
measurement_num = data_length / num_parameter;
|
||
measurement_after_trigger = 1 + static_cast<std::size_t>( 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<typename T>
|
||
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<char *>(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<char *>( &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();
|
||
|
||
}
|
||
|
||
}
|