Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 47 additions & 12 deletions lib/include/kickcat/ESI/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,40 @@
#include <vector>

#include "kickcat/CoE/OD.h"
#include "kickcat/protocol.h"

namespace kickcat::ESI
{
struct SyncManager
{
kickcat::SyncManager::Type type = kickcat::SyncManager::Unused;
uint16_t min_size = 0;
uint16_t max_size = 0;
uint16_t default_size = 0;
uint16_t start_address = 0;
uint8_t control_byte = 0;
uint8_t enable = 0;
bool is_virtual = false;
bool op_only = false;
};

struct SyncUnit
{
bool separate_su = false;
bool separate_frame = false;
bool frame_repeat_support = false;
};

struct Fmmu
{
fmmu::Type type = fmmu::Unused;
// -1 when the attribute is absent. ESI Sm/Su attributes index into
// the device's <Sm>/<Su> declaration order.
int sm = -1;
int su = -1;
bool op_only = false;
};

struct DeviceSummary
{
std::string type;
Expand All @@ -30,18 +61,22 @@ namespace kickcat::ESI

struct Device
{
std::string type;
uint32_t product_code = 0;
uint32_t revision_no = 0;
uint32_t serial_no = 0;
std::string name;
std::string group_type;
uint16_t profile_no = 0;

std::string vendor_name;
uint32_t vendor_id = 0;

CoE::Dictionary dictionary;
std::string type;
uint32_t product_code = 0;
uint32_t revision_no = 0;
uint32_t serial_no = 0;
std::string name;
std::string group_type;
uint16_t profile_no = 0;

std::string vendor_name;
uint32_t vendor_id = 0;

std::vector<SyncManager> sync_managers;
std::vector<SyncUnit> sync_units;
std::vector<Fmmu> fmmus;

CoE::Dictionary dictionary;
};
}

Expand Down
8 changes: 6 additions & 2 deletions lib/include/kickcat/ESI/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ namespace kickcat::ESI
tinyxml2::XMLElement* selectDevice(DeviceFilter const& filter);
DeviceSummary summarize (tinyxml2::XMLElement* device);

CoE::Dictionary buildDictionary(tinyxml2::XMLElement* device, tinyxml2::XMLElement* profile);
void parseSyncManagers(tinyxml2::XMLElement* device, std::vector<SyncManager>& out);
void parseSyncUnits (tinyxml2::XMLElement* device, std::vector<SyncUnit>& out);
void parseFmmus (tinyxml2::XMLElement* device, std::vector<Fmmu>& out);

CoE::Dictionary buildDictionary(tinyxml2::XMLElement* profile,
std::vector<SyncManager> const& sms);

std::vector<uint8_t> loadHexBinary(tinyxml2::XMLElement* node);
std::vector<uint8_t> loadStringData(tinyxml2::XMLElement* node);
Expand All @@ -70,7 +75,6 @@ namespace kickcat::ESI
std::string profile_no_;

static const std::unordered_map<std::string, CoE::DataType> BASIC_TYPES;
static const std::unordered_map<std::string, uint8_t> SM_CONF;
};
}

Expand Down
2 changes: 1 addition & 1 deletion lib/include/kickcat/Mailbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ namespace kickcat::mailbox::request
bool toggle; // for SDO segmented transfer

//
void generateSMConfig(SyncManager SM[2]);
void generateSMConfig(SyncManager::Register SM[2]);

// messages factory
std::shared_ptr<AbstractMessage> createSDO(uint16_t index, uint8_t subindex, bool CA, uint8_t request, void* data, uint32_t* data_size, nanoseconds timeout = 20ms);
Expand Down
109 changes: 64 additions & 45 deletions lib/include/kickcat/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,34 +384,35 @@ namespace kickcat

std::string toString(ErrorCounters const& counters);

struct SyncManager
namespace SyncManager
{
uint16_t start_address;
uint16_t length;
uint8_t control;
uint8_t status;
uint8_t activate;
uint8_t pdi_control;
} __attribute__((__packed__));
struct Register
{
uint16_t start_address;
uint16_t length;
uint8_t control;
uint8_t status;
uint8_t activate;
uint8_t pdi_control;
} __attribute__((__packed__));
}


constexpr uint8_t SM_CONTROL_MODE_MASK = 0x03;
constexpr uint8_t SM_CONTROL_MODE_BUFFERED = 0x00;
constexpr uint8_t SM_CONTROL_MODE_MAILBOX = 0x02;
constexpr uint8_t SM_CONTROL_DIRECTION_MASK = 0x0C;
constexpr uint8_t SM_CONTROL_DIRECTION_READ = 0x00; // ECAT read access, PDI write access
constexpr uint8_t SM_CONTROL_DIRECTION_WRITE = 0x04; // ECAT write access, PDI read access
constexpr uint8_t SM_CONTROL_INTERRUPT_ECAT_MASK = 0x10;
constexpr uint8_t SM_CONTROL_INTERRUPT_ECAT_DISABLED= 0x00;
constexpr uint8_t SM_CONTROL_INTERRUPT_ECAT_ENABLED = 0x10;
constexpr uint8_t SM_CONTROL_INTERRUPT_AL_MASK = 0x20;
constexpr uint8_t SM_CONTROL_INTERRUPT_AL_DISABLED = 0x00;
constexpr uint8_t SM_CONTROL_INTERRUPT_AL_ENABLED = 0x20;
constexpr uint8_t SM_CONTROL_WATCHDOG_MASK = 0x40;
constexpr uint8_t SM_CONTROL_WATCHDOG_DISABLED = 0x00;
constexpr uint8_t SM_CONTROL_WATCHDOG_ENABLED = 0x40;
constexpr uint8_t SYNC_MANAGER_CONTROL_OPERATION_MODE_MASK = 0x03; // bits [1:0]
constexpr uint8_t SYNC_MANAGER_CONTROL_DIRECTION_MASK = 0x0C; // bits [3:2]
constexpr uint8_t SM_CONTROL_OPERATION_MODE_MASK = 0x03; // bits [1:0]
constexpr uint8_t SM_CONTROL_MODE_BUFFERED = 0x00;
constexpr uint8_t SM_CONTROL_MODE_MAILBOX = 0x02;
constexpr uint8_t SM_CONTROL_DIRECTION_MASK = 0x0C; // bits [3:2]
constexpr uint8_t SM_CONTROL_DIRECTION_READ = 0x00; // ECAT read access, PDI write access
constexpr uint8_t SM_CONTROL_DIRECTION_WRITE = 0x04; // ECAT write access, PDI read access
constexpr uint8_t SM_CONTROL_INTERRUPT_ECAT_MASK = 0x10;
constexpr uint8_t SM_CONTROL_INTERRUPT_ECAT_DISABLED = 0x00;
constexpr uint8_t SM_CONTROL_INTERRUPT_ECAT_ENABLED = 0x10;
constexpr uint8_t SM_CONTROL_INTERRUPT_AL_MASK = 0x20;
constexpr uint8_t SM_CONTROL_INTERRUPT_AL_DISABLED = 0x00;
constexpr uint8_t SM_CONTROL_INTERRUPT_AL_ENABLED = 0x20;
constexpr uint8_t SM_CONTROL_WATCHDOG_MASK = 0x40;
constexpr uint8_t SM_CONTROL_WATCHDOG_DISABLED = 0x00;
constexpr uint8_t SM_CONTROL_WATCHDOG_ENABLED = 0x40;

constexpr uint8_t SM_ACTIVATE_ENABLE = (1 << 0);
constexpr uint8_t SM_ACTIVATE_REPEAT_REQ = (1 << 1);
Expand All @@ -422,29 +423,47 @@ namespace kickcat
constexpr uint8_t SM_STATUS_IRQ_READ = (1 << 1);
constexpr uint8_t SM_STATUS_MAILBOX = (1 << 3);

enum SyncManagerType
namespace SyncManager
{
Unused = 0,
MailboxOut = 1,
MailboxIn = 2,
Output = 3,
Input = 4 // slave to master
};
char const* toString(SyncManagerType const& type);
constexpr uint16_t addressSM(uint8_t index) { return static_cast<uint16_t>(reg::SYNC_MANAGER + index * sizeof(SyncManager)); };
enum Type : uint8_t
{
Unused = 0,
MailboxOut = 1,
MailboxIn = 2,
Output = 3,
Input = 4 // slave to master
};
char const* toString(Type const& type);
void fromString(std::string_view text, Type& out);
}

struct FMMU
namespace fmmu
{
uint32_t logical_address;
uint16_t length;
uint8_t logical_start_bit;
uint8_t logical_stop_bit;
uint16_t physical_address;
uint8_t physical_start_bit;
uint8_t type;
uint8_t activate;
uint8_t reserved[3];
} __attribute__((__packed__));
enum Type : uint8_t
{
Unused = 0,
Outputs = 1,
Inputs = 2,
MBoxState = 3,
};
char const* toString(Type const& type);
void fromString(std::string_view text, Type& out);

struct Register
{
uint32_t logical_address;
uint16_t length;
uint8_t logical_start_bit;
uint8_t logical_stop_bit;
uint16_t physical_address;
uint8_t physical_start_bit;
uint8_t type;
uint8_t activate;
uint8_t reserved[3];
} __attribute__((__packed__));
}

constexpr uint16_t addressSM(uint8_t index) { return static_cast<uint16_t>(reg::SYNC_MANAGER + index * sizeof(SyncManager::Register)); };

namespace eeprom // addresses are in words!
{
Expand Down
30 changes: 15 additions & 15 deletions lib/master/src/Bus.cc
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ namespace kickcat
{
if (slave.sii.info.mailbox_protocol)
{
SyncManager SM[2];
SyncManager::Register SM[2];
slave.mailbox.generateSMConfig(SM);
link_->addDatagram(Command::FPWR, createAddress(slave.address, reg::SYNC_MANAGER), SM, process, error);
}
Expand Down Expand Up @@ -412,7 +412,7 @@ namespace kickcat
}

Slave::PIMapping* mapping = &slave.input;
if (sm[i] == SyncManagerType::Output)
if (sm[i] == SyncManager::Output)
{
mapping = &slave.output;
}
Expand Down Expand Up @@ -441,7 +441,7 @@ namespace kickcat
else
{
// unsupported mailbox: use SII to get the mapping size
auto siiMapping = [&](Slave::PIMapping* mapping, std::vector<eeprom::PDOMapping> const& PDOs, SyncManagerType type)
auto siiMapping = [&](Slave::PIMapping* mapping, std::vector<eeprom::PDOMapping> const& PDOs, SyncManager::Type type)
{
mapping->sync_manager = -1;
mapping->size = 0;
Expand All @@ -467,8 +467,8 @@ namespace kickcat
}
};

siiMapping(&slave.output, slave.sii.RxPDO, SyncManagerType::Output);
siiMapping(&slave.input, slave.sii.TxPDO, SyncManagerType::Input);
siiMapping(&slave.output, slave.sii.RxPDO, SyncManager::Output);
siiMapping(&slave.input, slave.sii.TxPDO, SyncManager::Input);
}
}
}
Expand Down Expand Up @@ -804,7 +804,7 @@ namespace kickcat

void Bus::configureFMMUs()
{
auto prepareDatagrams = [this](Slave& slave, Slave::PIMapping& mapping, SyncManagerType type)
auto prepareDatagrams = [this](Slave& slave, Slave::PIMapping& mapping, SyncManager::Type type)
{

if (mapping.bsize == 0)
Expand All @@ -830,15 +830,15 @@ namespace kickcat
// Get SyncManager configuration from SII
auto& sii_sm = slave.sii.syncManagers[mapping.sync_manager];

SyncManager sm;
FMMU fmmu;
std::memset(&sm, 0, sizeof(SyncManager));
std::memset(&fmmu, 0, sizeof(FMMU));
SyncManager::Register sm;
fmmu::Register fmmu;
std::memset(&sm, 0, sizeof(SyncManager::Register));
std::memset(&fmmu, 0, sizeof(fmmu::Register));

uint16_t targeted_fmmu = reg::FMMU; // FMMU0 - outputs
sm.control = 0x64; // 3 buffers - write acces - PDI IRQ ON - Watchdog trigger
fmmu.type = 2; // write access
if (type == SyncManagerType::Input)
if (type == SyncManager::Input)
{
sm.control = 0x20; // 3 buffers - read acces - PDI IRQ ON
fmmu.type = 1; // read access
Expand Down Expand Up @@ -868,8 +868,8 @@ namespace kickcat

for (auto& slave : slaves_)
{
prepareDatagrams(slave, slave.input, SyncManagerType::Input);
prepareDatagrams(slave, slave.output, SyncManagerType::Output);
prepareDatagrams(slave, slave.input, SyncManager::Input);
prepareDatagrams(slave, slave.output, SyncManager::Output);
}

link_->processDatagrams();
Expand Down Expand Up @@ -898,8 +898,8 @@ namespace kickcat
{
for (auto const& entry : entries)
{
FMMU fmmu;
std::memset(&fmmu, 0, sizeof(FMMU));
fmmu::Register fmmu;
std::memset(&fmmu, 0, sizeof(fmmu::Register));
fmmu.logical_address = frame.address + entry.byte_offset;
fmmu.length = 1;
fmmu.logical_start_bit = entry.bit_position;
Expand Down
2 changes: 1 addition & 1 deletion lib/master/src/Prints.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace kickcat
os << "SM[" << std::dec << i << "] config\n";
os << " physical address: " << "0x" << std::hex << sm.start_address << "\n";
os << " length: " << std::dec << sm.length << "\n";
os << " type: " << std::dec << toString(static_cast<SyncManagerType>(sm.type)) << "\n";
os << " type: " << std::dec << toString(static_cast<SyncManager::Type>(sm.type)) << "\n";
os << " control: " << std::hex << (int)sm.control_register << "\n";
}

Expand Down
12 changes: 6 additions & 6 deletions lib/slave/include/kickcat/AbstractESC.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@ namespace kickcat
uint16_t start_address;
uint16_t length;
uint8_t control;
SyncManagerType type;
SyncManager::Type type;
};

constexpr SyncManagerConfig SYNC_MANAGER_PI_IN(uint8_t index, uint16_t address, uint16_t length)
{ return {index, address, length, 0x20, SyncManagerType::Input}; }
{ return {index, address, length, 0x20, SyncManager::Input}; }

constexpr SyncManagerConfig SYNC_MANAGER_PI_OUT(uint8_t index, uint16_t address, uint16_t length)
{ return {index, address, length, 0x64, SyncManagerType::Output}; }
{ return {index, address, length, 0x64, SyncManager::Output}; }

constexpr SyncManagerConfig SYNC_MANAGER_MBX_IN(uint8_t index, uint16_t address, uint16_t length)
{ return {index, address, length, 0x02, SyncManagerType::MailboxIn}; }
{ return {index, address, length, 0x02, SyncManager::MailboxIn}; }

constexpr SyncManagerConfig SYNC_MANAGER_MBX_OUT(uint8_t index, uint16_t address, uint16_t length)
{ return {index, address, length, 0x06, SyncManagerType::MailboxOut}; }
{ return {index, address, length, 0x06, SyncManager::MailboxOut}; }


namespace mailbox::response
Expand Down Expand Up @@ -59,7 +59,7 @@ namespace kickcat
/// \return Number of bytes written or a negative errno code otherwise
virtual int32_t write(uint16_t address, void const* data, uint16_t size) = 0;

std::tuple<uint8_t, SyncManager> findSm(uint16_t controlMode);
std::tuple<uint8_t, SyncManager::Register> findSm(uint16_t controlMode);
void activateSm(SyncManagerConfig const& sm);
void deactivateSm(SyncManagerConfig const& sm);

Expand Down
6 changes: 3 additions & 3 deletions lib/slave/include/kickcat/ESC/EmulatedESC.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ namespace kickcat
uint32_t phy_port_status;
uint8_t padding23[228];

FMMU fmmu[16];
fmmu::Register fmmu[16];
uint8_t padding24[0x100];

SyncManager sync_manager[16];
SyncManager::Register sync_manager[16];
uint8_t padding25[128];

// DC
Expand Down Expand Up @@ -165,7 +165,7 @@ namespace kickcat
uint8_t access;
uint16_t address;
uint16_t size;
SyncManager* registers;
SyncManager::Register* registers;
};
std::vector<SM> syncs_;

Expand Down
Loading