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

198 lines
4.3 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();
}
}