sitara_depot/components/free_rtos/ethernet_industry/eth_ecat_eeprom.hpp

140 lines
4.5 KiB
C++

/*
* 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 <kernel/dpl/ClockP.h>
#include <free_rtos/ethernet_industry/eth_ecat_datagram.hpp>
#include "free_rtos/ethernet_industry/eth_ecat_telegram.hpp"
namespace free_rtos {
namespace eeprom {
class EEPROM {
public:
EEPROM(telegram::EcatTelegram& telegram)
: telegram_{telegram} { }
template<typename TypeT>
bool wait_busy(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address) {
using TCommand= command::EcatCommand<TypeT, command::RD>;
std::array<uint16_t, 2> eeprom_config_status{0x0000, 0x0000};
datagram::EcatDatagram<TCommand, std::array<uint16_t, 2>> 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<typename TypeT>
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<TypeT, command::WR>;
std::array<uint16_t, 2> request{eeprom_cmd, eeprom_address};
datagram::EcatDatagram<TCommand, std::array<uint16_t, 2>> datagram{ {{slave_address, ECT_REG_EEPCTL}}, expected_wkc, request };
return telegram_.transfer(datagram);
}
template<typename TypeT, typename DirT, typename... DataTypes>
bool data_register(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, DataTypes&... data) {
using TCommand = command::EcatCommand<TypeT, DirT>;
datagram::EcatDatagram<TCommand, DataTypes...> datagram{ {{slave_address, ECT_REG_EEPDAT}}, expected_wkc, data... };
return telegram_.transfer(datagram);
}
template<typename TypeT, typename... DataTypes>
bool read(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) {
if(wait_busy<TypeT>(expected_wkc, slave_address) != true) {
DebugP_log((char*)"read, wait_busy() failed\r\n");
return false;
}
if(control_register<TypeT>(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<TypeT>(expected_wkc, slave_address) != true) {
DebugP_log((char*)"read, wait_busy() failed\r\n");
return false;
}
if(data_register<TypeT, command::RD, DataTypes...>(expected_wkc, slave_address, data...) != true) {
DebugP_log((char*)"read, data_register() failed\r\n");
return false;
}
if(wait_busy<TypeT>(expected_wkc, slave_address) != true){
DebugP_log((char*)"read, wait_busy() failed\r\n");
return false;
}
return true;
}
// 2 bytes (1 word) max
template<typename TypeT, typename... DataTypes>
bool write(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) {
if(wait_busy<TypeT>(expected_wkc, slave_address) != true) {
DebugP_log((char*)"write, wait_busy() failed\r\n");
return false;
}
if(data_register<TypeT, command::WR, DataTypes...>(expected_wkc, slave_address, data...) != true) {
DebugP_log((char*)"write, data_register() failed\r\n");
return false;
}
if(wait_busy<TypeT>(expected_wkc, slave_address) != true) {
DebugP_log((char*)"write, wait_busy() failed\r\n");
return false;
}
if(control_register<TypeT>( 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<TypeT>(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_ */