/* * ParametersStorage.hpp * * Created on: 19 февр. 2021 г. * Author: titov */ #ifndef UMLIBRARY_DRIVER_PARAMETERSSTORAGE_HPP_ #define UMLIBRARY_DRIVER_PARAMETERSSTORAGE_HPP_ #include "DataImageStorage.hpp" #include "../peripheral/ProtectedMemory.hh" #include "../systemic/SharedData.hh" #include #include namespace driver { template class ParametersStorage : public DataImageStorage { public: typedef driver::IParamStorage::Id Id; ParametersStorage( peripheral::IMemoryAccess & persistent, peripheral::protected_char * buff, std::size_t buff_size, std::pmr::memory_resource * task_buffer_memory ); bool flushParameterBuff( Id parameter_id ); void process(); private: std::deque< Id, std::pmr::polymorphic_allocator > tasks; struct ParameterState { enum Id { Idle, StartWriteOnce, WaitWriteOnce, UpdateCrc, StartWriteCrc, WaitWriteCrc, PrepareReadOnce, StartReadOnce, WaitReadOnce, }; }; typename ParameterState::Id parameter_state; }; } template driver::ParametersStorage::ParametersStorage( peripheral::IMemoryAccess & persistent, peripheral::protected_char * buff, std::size_t buff_size, std::pmr::memory_resource * task_buffer_memory ) : DataImageStorage(persistent, buff, buff_size), tasks(task_buffer_memory), parameter_state(ParameterState::Idle) {} template bool driver::ParametersStorage::flushParameterBuff( Id parameter_id ) { if( not DataImageStorage::data_ready or not DataImageStorage::image.show_setting_data_buff(parameter_id) ) return false; tasks.push_back(parameter_id); DataImageStorage::data_stored = false; return true; } template void driver::ParametersStorage::process() { DataImageStorage::process(); char * buff = DataImageStorage::buff; bool & data_stored = DataImageStorage::data_stored; DataImage & image = DataImageStorage::image; peripheral::IMemoryAccess & memory = DataImageStorage::memory; if( not DataImageStorage::isMemoryProcessing() ) switch(parameter_state) { case ParameterState::Idle: { if( not tasks.empty() ) { parameter_state = ParameterState::StartWriteOnce; } } break; case ParameterState::StartWriteOnce: { Id parameter = tasks.front(); std::pair par_buff = image.show_setting( parameter ); if( memory.write( par_buff.first, par_buff.first - buff, par_buff.second ) ) parameter_state = ParameterState::WaitWriteOnce; } break; case ParameterState::WaitWriteOnce: { if( memory.isWriteComplete() ) { parameter_state = ParameterState::UpdateCrc; } } break; case ParameterState::UpdateCrc: { Id parameter = tasks.front(); std::pair crc_buff = image.show_setting_crc( parameter ); if( peripheral::write_lock( crc_buff.first, crc_buff.second ) ) { image.update_data_crc( parameter ); peripheral::write_unlock( crc_buff.first, crc_buff.second ); parameter_state = ParameterState::StartWriteCrc; } } break; case ParameterState::StartWriteCrc: { Id parameter = tasks.front(); std::pair crc_buff = image.show_setting_crc( parameter ); if( memory.write( crc_buff.first, crc_buff.first - buff, crc_buff.second ) ) parameter_state = ParameterState::WaitWriteCrc; } break; case ParameterState::WaitWriteCrc: { if( memory.isWriteComplete() ) { parameter_state = ParameterState::StartReadOnce; } } break; case ParameterState::PrepareReadOnce: { Id parameter = tasks.front(); std::pair par_buff = image.show_setting( parameter ); } break; case ParameterState::StartReadOnce: { Id parameter = tasks.front(); std::pair par_buff = image.show_setting( parameter ); if( memory.read( par_buff.first, par_buff.first - buff, par_buff.second ) ) parameter_state = ParameterState::WaitReadOnce; } break; case ParameterState::WaitReadOnce: { Id parameter = tasks.front(); if( memory.isReadComplete() ) { if( image.check_data_crc(parameter) ) tasks.pop_front(); parameter_state = ParameterState::Idle; if( tasks.empty() ) data_stored = true; } } break; } } #endif /* UMLIBRARY_DRIVER_PARAMETERSSTORAGE_HPP_ */