sitara_depot/components/free_rtos/ethernet_industry/eth_ecat_telegram.cpp

186 lines
6.0 KiB
C++
Raw Normal View History

/*
* eth_ecat_telegram.cpp
*
* Created on: Jun 5, 2023
* Author: algin
*/
#include "free_rtos/ethernet_industry/eth_ecat_telegram.hpp"
namespace free_rtos {
namespace telegram {
const char EcatTelegramStatus::SuccessString[] = "Success !";
const char EcatTelegramStatus::BusyString[] = "Busy. Transfer in progress...";
const char EcatTelegramStatus::WarningTransferErrorString[] = "Warning ! Transfer error. Check error counters";
const char EcatTelegramStatus::WarningTimeoutErrorString[] = "Warning ! Connection timeout error. Check error counters";
const char EcatTelegramStatus::WarningWkcErrorString[] = "Warning ! WKC error. Check error counters";
const char EcatTelegramStatus::FatalErrorString[] = "Fatal error ! Transfer attempts exceeded";
const EcatDescription EcatTelegramStatus::descriptions[] = {
{EcatTelegramStatus::SuccessString, sizeof(EcatTelegramStatus::SuccessString)},
{EcatTelegramStatus::BusyString, sizeof(EcatTelegramStatus::BusyString)},
{EcatTelegramStatus::WarningTransferErrorString, sizeof(EcatTelegramStatus::WarningTransferErrorString)},
{EcatTelegramStatus::WarningTimeoutErrorString, sizeof(EcatTelegramStatus::WarningTimeoutErrorString)},
{EcatTelegramStatus::WarningWkcErrorString, sizeof(EcatTelegramStatus::WarningWkcErrorString)},
{EcatTelegramStatus::FatalErrorString, sizeof(EcatTelegramStatus::FatalErrorString)}
};
int32_t EcatTelegram::Process(uint8_t *p_data, uint32_t len) {
// TODO: Don't forget to subtract sizeof(TEthFrameHeader) !
unpack(p_data - sizeof(TEthFrameHeader));
/*
DebugP_log((char*)"Process started\r\n");
for(uint8_t *data = p_data; data < p_data + len; data++) {
DebugP_log((char*)"0x%01x ", *data);
}
DebugP_log((char*)"\r\n");
*/
rx_sem_.post();
return 0;
}
uint32_t EcatTelegram::Sender(uint8_t *p_data, size_t scatter_segment) {
uint8_t *raw = pack(p_data);
//DebugP_log((char*)"Sender started\r\n");
return raw - p_data;
}
uint8_t* EcatTelegram::pack(uint8_t *raw) {
TEthFrameHeader *p_eth_hdr = new(raw) TEthFrameHeader{ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
ETH_PROT_ECAT_LE };
TEcatFrameHeader *p_hdr = new(raw + sizeof(TEthFrameHeader)) TEcatFrameHeader{ .bits = { .length = 0,
.type = static_cast<uint16_t>(ec_network::PROTOCOL_TYPE) } };
uint8_t *p_datagram_first = raw + sizeof(TEthFrameHeader) + sizeof(TEcatFrameHeader);
uint8_t *p_datagram_last = p_datagram_first;
auto first = datagram_queue_.get_first();
2023-05-10 15:10:01 +03:00
(void)p_eth_hdr;
(void)p_hdr;
if(first == nullptr) {
return p_datagram_last;
}
p_datagram_last = first->pack_all(p_datagram_first);
p_hdr->bits.length = p_datagram_last - p_datagram_first;
return p_datagram_last;
}
uint8_t* EcatTelegram::unpack(uint8_t *raw) {
TEthFrameHeader *p_eth_hdr = reinterpret_cast<TEthFrameHeader*>(raw);
TEcatFrameHeader *p_hdr = reinterpret_cast<TEcatFrameHeader*>(raw + sizeof(TEthFrameHeader));
uint8_t *p_datagram_first = raw + sizeof(TEthFrameHeader) + sizeof(TEcatFrameHeader);
uint8_t *p_datagram_last = p_datagram_first;
auto first = datagram_queue_.get_first();
if(first == nullptr) {
return p_datagram_last;
}
p_datagram_last = first->unpack_all(p_datagram_first);
return p_datagram_last;
}
bool EcatTelegram::transfer() {
auto first = datagram_queue_.get_first();
uint32_t transfer_attempts = 0;
bool stat;
bool as_expected;
if(first == nullptr) {
status_.result = EcatTelegramResult::SUCCESS;
return true;
}
2023-05-10 15:10:01 +03:00
status_.result = EcatTelegramResult::BUSY;
first->reset_all_wkc();
2023-06-16 10:18:13 +03:00
while(1) {
transfer_attempts++;
if(transfer_attempts > max_transfer_attempts_) {
DebugP_log((char*)"%s\r\n", status_.get_description().string);
status_.attempts_exceeded_errors++;
status_.result = EcatTelegramResult::FATAL_ERROR;
DebugP_log((char*)"%s: %d\r\n", status_.get_description().string, status_.attempts_exceeded_errors);
break;
}
// stat = eth_stack_.send_pkt(port_id_, ETH_PROT_ECAT_LE, 1);
stat = tx_flow_.send(port_id_, this, 1);
if(stat == false) {
status_.transfer_errors++;
status_.result = EcatTelegramResult::WARNING_TRANSFER_ERROR;
//DebugP_log((char*)"%s: %d\r\n", status_.get_description().string, status_.transfer_errors);
continue;
}
if(rx_sem_.pend(connection_timeout_ticks_) != SystemP_SUCCESS) {
status_.transfer_errors++;
status_.result = EcatTelegramResult::WARNING_TIMEOUT_ERROR;
//DebugP_log((char*)"%s: %d\r\n", status_.get_description().string, status_.transfer_errors);
continue;
}
as_expected = first->all_as_expected();
if(as_expected == false) {
status_.expected_wkc_errors++;
status_.result = EcatTelegramResult::WARNING_WKC_ERROR;
//DebugP_log((char*)"%s: %d\r\n", status_.get_description().string, status_.expected_wkc_errors);
continue;
}
if(status_.result == EcatTelegramResult::BUSY) {
status_.result = EcatTelegramResult::SUCCESS;
}
break;
}
datagram_queue_.clear();
return (status_.result != EcatTelegramResult::FATAL_ERROR);
}
bool EcatTelegram::transfer(datagram::IEcatDatagram& next) {
2023-06-16 13:01:24 +03:00
datagram_queue_ + next;
return transfer();
2023-06-16 13:01:24 +03:00
}
bool EcatTelegram::transfer(queue::Queue<datagram::IEcatDatagram>& next) {
2023-06-16 13:01:24 +03:00
datagram_queue_ + next;
return transfer();
}
2023-06-16 13:01:24 +03:00
}
}