2023-05-03 14:01:32 +03:00
|
|
|
/*
|
|
|
|
|
* 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_
|
|
|
|
|
|
2023-05-23 10:17:24 +03:00
|
|
|
#include <kernel/dpl/ClockP.h>
|
|
|
|
|
|
2023-09-21 14:50:50 +03:00
|
|
|
#include "free_rtos/ethernet_industry/eth_ecat_datagram.hpp"
|
2023-06-26 18:22:30 +03:00
|
|
|
#include "free_rtos/ethernet_industry/eth_ecat_telegram.hpp"
|
2023-09-21 14:50:50 +03:00
|
|
|
#include "free_rtos/ethernet_industry/eth_ecat_custom_tuple.hpp"
|
2023-05-03 14:01:32 +03:00
|
|
|
|
|
|
|
|
namespace free_rtos {
|
|
|
|
|
|
|
|
|
|
namespace eeprom {
|
|
|
|
|
|
|
|
|
|
class EEPROM {
|
|
|
|
|
public:
|
2023-06-06 10:27:01 +03:00
|
|
|
EEPROM(telegram::EcatTelegram& telegram)
|
2023-05-03 14:01:32 +03:00
|
|
|
: telegram_{telegram} { }
|
|
|
|
|
|
|
|
|
|
template<typename TypeT>
|
2023-09-06 18:09:23 +03:00
|
|
|
bool wait_busy(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address) {
|
2023-05-23 10:17:24 +03:00
|
|
|
using TCommand= command::EcatCommand<TypeT, command::RD>;
|
2023-09-06 18:09:23 +03:00
|
|
|
|
2023-05-23 10:17:24 +03:00
|
|
|
std::array<uint16_t, 2> eeprom_config_status{0x0000, 0x0000};
|
2023-09-06 18:09:23 +03:00
|
|
|
datagram::EcatDatagram<TCommand, std::array<uint16_t, 2>> datagram{ {{slave_address, ECT_REG_EEPCFG}}, expected_wkc, eeprom_config_status };
|
|
|
|
|
bool status;
|
2023-05-03 14:01:32 +03:00
|
|
|
|
|
|
|
|
do {
|
2023-09-06 18:09:23 +03:00
|
|
|
status = telegram_.transfer(datagram);
|
|
|
|
|
} while((status == true) && ( ((eeprom_config_status[0] & 0xFF00) != 0) || ((eeprom_config_status[1] & EC_ESTAT_BUSY) != 0) ) );
|
|
|
|
|
|
|
|
|
|
return status;
|
2023-05-03 14:01:32 +03:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:17:24 +03:00
|
|
|
template<typename TypeT>
|
2023-09-06 18:09:23 +03:00
|
|
|
bool control_register(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, ec_ecmdtype eeprom_cmd, uint16_t eeprom_address) {
|
2023-05-23 10:17:24 +03:00
|
|
|
using TCommand = command::EcatCommand<TypeT, command::WR>;
|
|
|
|
|
|
2023-09-06 18:09:23 +03:00
|
|
|
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 };
|
2023-05-03 14:01:32 +03:00
|
|
|
|
2023-09-06 18:09:23 +03:00
|
|
|
return telegram_.transfer(datagram);
|
2023-05-03 14:01:32 +03:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:17:24 +03:00
|
|
|
template<typename TypeT, typename DirT, typename... DataTypes>
|
2023-09-06 18:09:23 +03:00
|
|
|
bool data_register(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, DataTypes&... data) {
|
2023-05-03 14:01:32 +03:00
|
|
|
using TCommand = command::EcatCommand<TypeT, DirT>;
|
|
|
|
|
|
2023-09-06 18:09:23 +03:00
|
|
|
datagram::EcatDatagram<TCommand, DataTypes...> datagram{ {{slave_address, ECT_REG_EEPDAT}}, expected_wkc, data... };
|
|
|
|
|
|
|
|
|
|
return telegram_.transfer(datagram);
|
2023-05-03 14:01:32 +03:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:17:24 +03:00
|
|
|
template<typename TypeT, typename... DataTypes>
|
2023-09-06 18:09:23 +03:00
|
|
|
bool read(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) {
|
2023-09-15 15:37:33 +03:00
|
|
|
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;
|
2023-05-03 14:01:32 +03:00
|
|
|
}
|
2023-09-21 14:50:50 +03:00
|
|
|
|
|
|
|
|
struct Reader {
|
|
|
|
|
template<typename DataT>
|
|
|
|
|
void operator()(DataT& data) {
|
|
|
|
|
free_rtos::RawData raw_data{};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename TypeT, typename... DataTypes>
|
|
|
|
|
bool read_block(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) {
|
|
|
|
|
custom_tuple<DataTypes&...> data_tuple{data...};
|
|
|
|
|
Reader functor{};
|
|
|
|
|
|
|
|
|
|
for_each(data_tuple, functor);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 10:17:24 +03:00
|
|
|
// 2 bytes (1 word) max
|
|
|
|
|
template<typename TypeT, typename... DataTypes>
|
2023-09-06 18:09:23 +03:00
|
|
|
bool write(const datagram::TEcatWkc expected_wkc, typename TypeT::TSlaveAddress& slave_address, uint16_t eeprom_address, DataTypes&... data) {
|
2023-09-15 15:37:33 +03:00
|
|
|
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;
|
2023-05-03 14:01:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2023-06-06 10:27:01 +03:00
|
|
|
telegram::EcatTelegram& telegram_;
|
2023-05-03 14:01:32 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_EEPROM_HPP_ */
|