sitara_depot/components/free_rtos/ethernet_industry/eth_ecat_eeprom.hpp

87 lines
3.0 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>
void wait_busy(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}}, eeprom_config_status };
do {
telegram_.transfer(datagram);
}while((datagram.get_wkc() < 0x0001) || ((eeprom_config_status[0] & 0xFF00) != 0) || ((eeprom_config_status[1] & EC_ESTAT_BUSY) != 0));
}
template<typename TypeT>
void control_register(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}}, request };
do {
telegram_.transfer(datagram);
} while(datagram.get_wkc() < 0x0001);
}
template<typename TypeT, typename DirT, typename... DataTypes>
void data_register(typename TypeT::TSlaveAddress& slave_address, DataTypes&... data) {
using TCommand = command::EcatCommand<TypeT, DirT>;
datagram::EcatDatagram<TCommand, DataTypes...> datagram{ {{slave_address, ECT_REG_EEPDAT}}, data... };
do {
telegram_.transfer(datagram);
} while(datagram.get_wkc() < 0x0001);
}
template<typename TypeT, typename... DataTypes>
void read(typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) {
wait_busy<TypeT>(slave_address);
control_register<TypeT>(slave_address, EC_ECMD_READ, eeprom_address);
wait_busy<TypeT>(slave_address);
data_register<TypeT, command::RD, DataTypes...>(slave_address, data...);
wait_busy<TypeT>(slave_address);
}
// 2 bytes (1 word) max
template<typename TypeT, typename... DataTypes>
void write(typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) {
wait_busy<TypeT>(slave_address);
data_register<TypeT, command::WR, DataTypes...>(slave_address, data...);
wait_busy<TypeT>(slave_address);
control_register<TypeT>(slave_address, EC_ECMD_WRITE, eeprom_address);
wait_busy<TypeT>(slave_address);
}
private:
telegram::EcatTelegram& telegram_;
};
}
}
#endif /* FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_EEPROM_HPP_ */