/* * ADS1259ReconfiguratedReader.h * * Created on: 9 июл. 2020 г. * Author: krugliy */ #ifndef UMLIBRARY_DRIVER_CHIPSET_ADS1259RECONFIGURATEDREADER_H_ #define UMLIBRARY_DRIVER_CHIPSET_ADS1259RECONFIGURATEDREADER_H_ #include "ADS1259ExtendedAdcReader.hh" #include "ADS1259ContModeAdcReader.hh" #include "ADS1259Configurator.hh" #include "ADS1259.hh" #include "../../math/math_inc.hh" #include "../../systemic/Timer.hh" namespace driver { namespace chipset { struct ADS1259SignalConfig { struct Setting { float coeff; float offset; bool isValid() const { using namespace std; return isfinite(coeff) and isfinite(offset); } }; bool configure( Setting & setting ); }; template class ADS1259ReconfiguratedReader : private ADS1259Configurator, private AdcReader { private: const bool & data_valid; bool config_complete = false; float coeff = NAN; float offset = NAN; bool need_reset = false; const uint32_t & adc_code; systemic::Timer data_pending; //Если невалидные данные поступают в течении заданного периода, то происходит перенастройка ИС. systemic::time_t setting_check_period; bool adc_readed = false; //!<Данные из АЦП вычитаны. mutable bool result_fetched = false; //!<Результат прочитан. public: bool configure( ADS1259SignalConfig::Setting & config ); void reset() { need_reset = true; } const bool & isValid() const { return data_valid; } //!Статус настроенности. const bool & isCompleted() const { return config_complete; }; operator float() const { if( result_fetched ) return NAN; else { result_fetched = true; return adc_readed ? adc_code * coeff + offset : NAN; } } void process(); static::size_t memory_demand() { return ADS1259Configurator::memory_demand(); } using ADS1259Configurator::add_postconfig_option; using typename AdcReader::CommandOperation; using typename AdcReader::ReadAdcOperation; ADS1259ReconfiguratedReader( const ADS1259::Parameters & parameters, peripheral::ISerialPort & port, unsigned int number_of_retries, unsigned int latency, std::pmr::memory_resource * memory, typename AdcReader::CommandOperation start_operation, typename AdcReader::ReadAdcOperation read_operation, systemic::time_t update_setting_period, systemic::time_t update_port ): ADS1259Configurator(parameters, port, number_of_retries, latency, memory), AdcReader(start_operation, read_operation, update_port), data_valid(AdcReader::is_data_valid()), adc_code(AdcReader::get_adc_code()), setting_check_period(update_setting_period) {} }; typedef ADS1259ReconfiguratedReader ADS1259ReReaderInPulseMode; typedef ADS1259ReconfiguratedReader ADS1259ReReaderInContMode; } /* namespace chipset */ } /* namespace driver */ template bool driver::chipset::ADS1259ReconfiguratedReader::configure(ADS1259SignalConfig::Setting &config) { bool result; if( result = config.isValid() ) { offset = config.offset; coeff = config.coeff; }; return result; } template void driver::chipset::ADS1259ReconfiguratedReader::process() { adc_readed = AdcReader::is_adc_readed(); // Обязательное условие, иначе будет софтлок на SpiOperationPack. const bool config_error = ADS1259Configurator::isError(); if( adc_readed ) result_fetched = false; if( not ADS1259Configurator::isCompleted() and not config_error ) ADS1259Configurator::process(); else { if( ( (need_reset or data_pending.delayElapsed() ) and adc_readed ) or config_error ) { config_complete = false; need_reset = false; ADS1259Configurator::reset(); data_pending.stop(); } else { if( not config_complete ) { config_complete = true; data_pending.start( setting_check_period ); } AdcReader::process(); if( adc_readed and data_valid ) data_pending.start( setting_check_period ); } } } #endif /* UMLIBRARY_DRIVER_CHIPSET_ADS1259RECONFIGURATEDREADER_H_ */