sitara_depot/components/free_rtos/ethernet_industry/eth_ecat_telegram.hpp

127 lines
3.4 KiB
C++
Raw Normal View History

/*
* eth_ecat_telegram.hpp
*
* Created on: Jun 5, 2023
* Author: algin
*/
#ifndef FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_TELEGRAM_HPP_
#define FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_TELEGRAM_HPP_
#include "free_rtos/ethernet/eth.hpp"
#include "free_rtos/timer/timer.hpp"
#include "free_rtos/profiler/quick_profiler_static.hpp"
#include "free_rtos/ethernet_industry/eth_ecat_datagram.hpp"
namespace free_rtos {
namespace telegram {
enum class EcatTelegramResult : uint16_t {
SUCCESS = 0,
BUSY,
WARNING_TRANSFER_ERROR,
WARNING_TIMEOUT_ERROR,
WARNING_WKC_ERROR,
FATAL_ERROR
};
struct EcatDescription {
const char* string;
const size_t length;
};
struct EcatTelegramStatus {
uint16_t transfer_errors{0x0000};
uint16_t expected_wkc_errors{0x0000};
uint16_t attempts_exceeded_errors{0x0000};
EcatTelegramResult result = EcatTelegramResult::BUSY;
const EcatDescription& get_description() {
return descriptions[static_cast<size_t>(result)];
}
private:
static const char SuccessString[];
static const char BusyString[];
static const char WarningTransferErrorString[];
static const char WarningTimeoutErrorString[];
static const char WarningWkcErrorString[];
static const char FatalErrorString[];
static const EcatDescription descriptions[];
};
class EcatTelegram : public Handler {
public:
EcatTelegram(Eth& eth, Timer& ecat_timer)
: eth_{eth}
, ecat_timer_(ecat_timer)
, tx_flow_{*eth.getTxFlowPtr()}
, eth_stack_{*eth.getEthStackPtr()} { }
const EcatTelegramStatus& get_status() {
return status_;
}
virtual int32_t Process(uint8_t *p_data, uint32_t len) override;
virtual uint32_t Sender(uint8_t *p_data, size_t scatter_segment) override;
void init(TEthMacPorts port_id, uint32_t period_microsec, uint32_t max_transfer_attempts) {
port_id_ = port_id;
period_microsec_ = period_microsec;
counter_timeout_ticks_ = (semaphore_timeout_ticks_*1000)/period_microsec;
max_transfer_attempts_ = max_transfer_attempts;
eth_.getEthStackPtr()->Register(ETH_PROT_ECAT_LE, this);
}
static uint32_t diff(uint32_t tick_counter_start, uint32_t tick_counter_current) {
uint32_t tick_counter_diff;
if(tick_counter_current >= tick_counter_start) {
tick_counter_diff = tick_counter_current - tick_counter_start;
}else{
tick_counter_diff = tick_counter_current + (0xFFFFFFFF - tick_counter_start);
}
return tick_counter_diff;
}
bool transfer(datagram::IEcatDatagram& next);
bool transfer(queue::Queue<datagram::IEcatDatagram>& next);
private:
static constexpr uint32_t semaphore_timeout_ticks_ = 2;
Eth& eth_;
Timer& ecat_timer_;
EthTxFlowIface& tx_flow_;
EthStackIface& eth_stack_;
TEthMacPorts port_id_;
uint32_t period_microsec_{250};
uint32_t counter_timeout_ticks_{8};
uint32_t max_transfer_attempts_{4};
free_rtos::Semaphore rx_sem_;
uint8_t idx_{0x00};
queue::Queue<datagram::IEcatDatagram> datagram_queue_;
2023-06-16 10:18:13 +03:00
//datagram::IEcatDatagram *datagram_queue_{nullptr};
EcatTelegramStatus status_{0x0000, 0x0000, 0x0000, EcatTelegramResult::BUSY};
bool transfer();
2023-06-16 13:01:24 +03:00
uint8_t* pack(uint8_t *raw);
uint8_t* unpack(uint8_t *raw);
};
}
}
#endif /* FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_TELEGRAM_HPP_ */