/* * eth_ecat_eeprom.hpp * * Created on: May 2, 2023 * Author: algin */ #ifndef FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_EEPROM_HPP_ #define FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_EEPROM_HPP_ #include #include "free_rtos/ethernet_industry/eth_ecat_datagram.hpp" #include "free_rtos/ethernet_industry/eth_ecat_telegram.hpp" #include "free_rtos/ethernet_industry/eth_ecat_custom_tuple.hpp" namespace free_rtos { namespace eeprom { class EEPROM { public: EEPROM(telegram::EcatTelegram& telegram) : telegram_{telegram} { } template bool wait_busy(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address) { using TCommand= command::EcatCommand; std::array eeprom_config_status{0x0000, 0x0000}; datagram::EcatDatagram> datagram{ {{slave_address, ECT_REG_EEPCFG}}, expected_wkc, eeprom_config_status }; bool status; do { status = telegram_.transfer(datagram); } while((status == true) && ( ((eeprom_config_status[0] & 0xFF00) != 0) || ((eeprom_config_status[1] & EC_ESTAT_BUSY) != 0) ) ); return status; } template bool control_register(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, ec_ecmdtype eeprom_cmd, uint16_t eeprom_address) { using TCommand = command::EcatCommand; std::array request{eeprom_cmd, eeprom_address}; datagram::EcatDatagram> datagram{ {{slave_address, ECT_REG_EEPCTL}}, expected_wkc, request }; return telegram_.transfer(datagram); } template bool data_register(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, DataTypes&... data) { using TCommand = command::EcatCommand; datagram::EcatDatagram datagram{ {{slave_address, ECT_REG_EEPDAT}}, expected_wkc, data... }; return telegram_.transfer(datagram); } template bool read(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) { if(wait_busy(expected_wkc, slave_address) != true) { DebugP_log((char*)"read, wait_busy() failed\r\n"); return false; } if(control_register(expected_wkc, slave_address, EC_ECMD_READ, eeprom_address) != true) { DebugP_log((char*)"read, control_register() is failed\r\n"); return false; } if(wait_busy(expected_wkc, slave_address) != true) { DebugP_log((char*)"read, wait_busy() failed\r\n"); return false; } if(data_register(expected_wkc, slave_address, data...) != true) { DebugP_log((char*)"read, data_register() failed\r\n"); return false; } if(wait_busy(expected_wkc, slave_address) != true){ DebugP_log((char*)"read, wait_busy() failed\r\n"); return false; } return true; } struct Reader { template void operator()(DataT& data) { free_rtos::RawData raw_data{}; } }; template bool read_block(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) { custom_tuple data_tuple{data...}; Reader functor{}; for_each(data_tuple, functor); return true; } // 2 bytes (1 word) max template bool write(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) { if(wait_busy(expected_wkc, slave_address) != true) { DebugP_log((char*)"write, wait_busy() failed\r\n"); return false; } if(data_register(expected_wkc, slave_address, data...) != true) { DebugP_log((char*)"write, data_register() failed\r\n"); return false; } if(wait_busy(expected_wkc, slave_address) != true) { DebugP_log((char*)"write, wait_busy() failed\r\n"); return false; } if(control_register( expected_wkc, slave_address, EC_ECMD_WRITE, eeprom_address) != true) { DebugP_log((char*)"write, control_register() is failed\r\n"); return false; } if(wait_busy(expected_wkc, slave_address) != true) { DebugP_log((char*)"write, wait_busy() failed\r\n"); return false; } return true; } private: telegram::EcatTelegram& telegram_; }; } } #endif /* FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_EEPROM_HPP_ */