diff --git a/components/free_rtos/ethernet_industry/eth_ecat_api.cpp b/components/free_rtos/ethernet_industry/eth_ecat_api.cpp index 2c042cf..a9398ac 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_api.cpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_api.cpp @@ -9,6 +9,17 @@ namespace free_rtos { +/* + * Порядок инициализации: + * Инициализировать и открыть драйвер eth_.Init(...), eth_.Open() + * Вызвать EthEcatApi::init(eth_); + * Создать служебный поток ecat_task_.Create(...) с вызовом EthEcatApi::process() + * Вызвать EthEcatApi::config_init(...) + * Создать пользовательский поток ecat_task_pdo_.Create(...) + * Для чтения/записи данных в пользовательском потоке вызвать + * pdo_write(...), pdo_read(...) или pdo_write_async(...), pdo_read_async(...) + */ + Eth *EthEcatApi::eth_{nullptr}; void EthEcatApi::init(Eth& eth) { diff --git a/components/free_rtos/ethernet_industry/eth_ecat_buffer.cpp b/components/free_rtos/ethernet_industry/eth_ecat_buffer.cpp index 134c086..5494db4 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_buffer.cpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_buffer.cpp @@ -23,7 +23,11 @@ void EthEcatBuffer::init(uint16_t rx_eeprom_addr, uint16_t tx_eeprom_addr) { for(EcatSlave& slave : slaves) { buffer_slaves_.emplace_back(EcatBufferSlave{slave}); } - +/* + for(EcatBufferSlave& buffer_slave : buffer_slaves_) { + buffer_slave.read_info_from_eeprom(eeprom); + } +*/ for(EcatBufferSlave& buffer_slave : buffer_slaves_) { buffer_slave.read_buffer_info_from_eeprom(eeprom, rx_eeprom_addr, tx_eeprom_addr); } diff --git a/components/free_rtos/ethernet_industry/eth_ecat_buffer.hpp b/components/free_rtos/ethernet_industry/eth_ecat_buffer.hpp index 2f1afe8..32179e6 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_buffer.hpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_buffer.hpp @@ -17,8 +17,8 @@ namespace free_rtos { enum { - ECT_PDOOUTPUTOFFSET = 0x1100, // write, output, rx buffer offset - ECT_PDOINPUTOFFSET = 0x1400 // read, input, tx buffer offset + ECT_PDOOUTPUTOFFSET = 0x1100, // 0x1100 write, output, rx buffer offset + ECT_PDOINPUTOFFSET = 0x1400 // 0x1400, 0x1140 read, input, tx buffer offset }; enum { @@ -153,6 +153,20 @@ public: return fmmu_properties_read_; } + template + void read_info_from_eeprom(eeprom::EEPROM& eeprom) { + auto slave_address = slave_.get_slave_address(); + uint32_t word{0x00000000}; + + for(uint16_t addr = 0x0000; addr < 128; addr += 2) { + eeprom.read(slave_address, addr, word); + + DebugP_log((char*)"0x%04x \r\n", word); + } + + DebugP_log((char*)"\r\n"); + } + template void read_buffer_info_from_eeprom(eeprom::EEPROM& eeprom, uint16_t rx_eeprom_addr, uint16_t tx_eeprom_addr) { auto slave_address = slave_.get_slave_address(); diff --git a/components/free_rtos/ethernet_industry/eth_ecat_custom_promise.hpp b/components/free_rtos/ethernet_industry/eth_ecat_custom_promise.hpp index 6193c41..7940b46 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_custom_promise.hpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_custom_promise.hpp @@ -189,6 +189,56 @@ private: Future future_; }; +/* +Объект FunctorT реализует пользователь под собственные нужды и должен иметь вид + +class UserFunctor { +public: + // В конструктор можно передать переменные из пользовательского контекста + UserFunctor(address::Offset offset, std::vector& data) + : offset_{offset} + , data_{data} { } + + bool get_ready() { + return ready_; + } + + void operator()(uint8_t* process_data, uint32_t len) { + // Обработка коллбека пользователем + size_t size = data_.size() * sizeof(uint8_t); + + memcpy(data_.data(), process_data + offset_, size); + + ready_ = true; + + // DebugP_log((char*)"Запрос обработан !\r\n"); + } + +private: + // Переменные из пользовательского контекста + address::Offset offset_{0}; + std::vector& data_; + + bool ready_{false}; +}; + +*/ + +template +class FunctorPromise : public IPromise { +public: + FunctorPromise(FunctorT& functor) + : IPromise{0} + , functor_(functor) { } + + virtual void set_value(uint8_t* process_data, uint32_t len) override { + functor_(process_data, len); + } + +private: + FunctorT& functor_; +}; + } // namespace custom_promise } // namespace free_rtos diff --git a/components/free_rtos/ethernet_industry/eth_ecat_telegram.cpp b/components/free_rtos/ethernet_industry/eth_ecat_telegram.cpp index 8b41422..5475519 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_telegram.cpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_telegram.cpp @@ -68,8 +68,17 @@ uint8_t* EcatTelegram::unpack(uint8_t *raw) { uint8_t *p_datagram_last = p_datagram_first; datagram::IEcatDatagram *next = datagram_queue_; - (void)p_eth_hdr; - (void)p_hdr; + if(p_eth_hdr->prot_id != ETH_PROT_ECAT_LE) { + DebugP_log((char*)"Error: wrong protocol ID\r\n"); + + return raw; + } + + if(p_hdr->bits.type != static_cast(ec_network::PROTOCOL_TYPE)) { + DebugP_log((char*)"Error: wrong ethercat protocol type\r\n"); + + return raw; + } while(next != nullptr) { p_datagram_last = next->unpack(p_datagram_last); @@ -82,9 +91,6 @@ uint8_t* EcatTelegram::unpack(uint8_t *raw) { void EcatTelegram::transfer(datagram::IEcatDatagram& first) { datagram_queue_ = &first; - //uint8_t *raw = pack(buffer_out_.data); - //bool stat = tx_flow_.send(port_id_, buffer_out_.data, raw - buffer_out_.data); - bool stat = eth_stack_.send_pkt(port_id_, ETH_PROT_ECAT_LE, 1); if(stat == false) { diff --git a/components/free_rtos/ethernet_industry/eth_ecat_telegram.hpp b/components/free_rtos/ethernet_industry/eth_ecat_telegram.hpp index 526e066..b9d40fd 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_telegram.hpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_telegram.hpp @@ -20,7 +20,6 @@ class EcatTelegram : public Handler { public: EcatTelegram(Eth& eth) : eth_{eth} - , tx_flow_{*eth.getTxFlowPtr()} , eth_stack_{*eth.getEthStackPtr()} { } virtual int32_t Process(uint8_t *p_data, uint32_t len) override; @@ -35,7 +34,6 @@ public: private: Eth& eth_; - EthTxFlowIface& tx_flow_; EthStackIface& eth_stack_; TEthMacPorts port_id_;