Skip to content

Commit 77dc022

Browse files
authored
Emergency messages (#13)
* Fix: wrong working counter check when setting addresses * Add CoE emergency messages reception
1 parent c749ca9 commit 77dc022

File tree

7 files changed

+109
-28
lines changed

7 files changed

+109
-28
lines changed

include/kickcat/Error.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace kickcat
1717
#ifdef DEBUG
1818
#define DEBUG_PRINT(...) do { fprintf(stderr, "DEBUG: %s:%d: ", __FILE__, __LINE__); fprintf(stderr, ##__VA_ARGS__); } while(0);
1919
#else
20-
#define DEBUG_PRINT(fmt, ...)
20+
#define DEBUG_PRINT(...)
2121
#endif
2222

2323
struct Error : public std::exception

include/kickcat/Mailbox.h

+34-18
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ namespace kickcat
1212
enum class ProcessingResult
1313
{
1414
NOOP,
15+
CONTINUE,
1516
FINALIZE,
16-
CONTINUE
17+
FINALIZE_AND_KEEP
1718
};
1819

1920
namespace MessageStatus
@@ -57,7 +58,31 @@ namespace kickcat
5758
uint32_t status_; // message current status
5859
};
5960

60-
class SDOMessage : public AbstractMessage
61+
struct Mailbox
62+
{
63+
uint16_t recv_offset;
64+
uint16_t recv_size;
65+
uint16_t send_offset;
66+
uint16_t send_size;
67+
68+
bool can_read; // data available on the slave
69+
bool can_write; // free space for a new message on the slave
70+
uint8_t counter{0}; // session handle, from 1 to 7
71+
bool toggle; // for SDO segmented transfer
72+
73+
std::shared_ptr<AbstractMessage> createSDO(uint16_t index, uint8_t subindex, bool CA, uint8_t request, void* data, uint32_t* data_size);
74+
75+
bool receive(uint8_t const* raw_message);
76+
std::queue<std::shared_ptr<AbstractMessage>> to_send; // message waiting to be sent
77+
std::list <std::shared_ptr<AbstractMessage>> to_process; // message already sent, waiting for an answer
78+
79+
uint8_t nextCounter();
80+
81+
std::vector<mailbox::Emergency> emergencies;
82+
private:
83+
};
84+
85+
class SDOMessage : public AbstractMessage
6186
{
6287
public:
6388
SDOMessage(uint16_t mailbox_size, uint16_t index, uint8_t subindex, bool CA, uint8_t request, void* data, uint32_t* data_size);
@@ -78,26 +103,17 @@ namespace kickcat
78103
uint32_t* client_data_size_;
79104
};
80105

81-
struct Mailbox
106+
class EmergencyMessage : public AbstractMessage
82107
{
83-
uint16_t recv_offset;
84-
uint16_t recv_size;
85-
uint16_t send_offset;
86-
uint16_t send_size;
87-
88-
bool can_read; // data available on the slave
89-
bool can_write; // free space for a new message on the slave
90-
uint8_t counter{0}; // session handle, from 1 to 7
91-
bool toggle; // for SDO segmented transfer
92-
93-
std::shared_ptr<AbstractMessage> createSDO(uint16_t index, uint8_t subindex, bool CA, uint8_t request, void* data, uint32_t* data_size);
108+
public:
109+
EmergencyMessage(Mailbox& mailbox);
110+
virtual ~EmergencyMessage() = default;
94111

95-
bool receive(uint8_t const* raw_message);
96-
std::queue<std::shared_ptr<AbstractMessage>> to_send; // message waiting to be sent
97-
std::list <std::shared_ptr<AbstractMessage>> to_process; // message already sent, waiting for an answer
112+
bool needAcknowledge() const override { return false; }
113+
ProcessingResult process(uint8_t const* received) override;
98114

99-
uint8_t nextCounter();
100115
private:
116+
Mailbox& mailbox_;
101117
};
102118
}
103119

include/kickcat/protocol.h

+26-5
Original file line numberDiff line numberDiff line change
@@ -271,17 +271,26 @@ namespace kickcat
271271
uint8_t device_order_id;
272272
uint8_t device_name_id;
273273
uint8_t reserved_A;
274-
uint8_t CoE_details;
274+
uint8_t SDO_set : 1, // CoE details
275+
SDO_info : 1,
276+
PDO_assign : 1,
277+
PDO_configuration : 1,
278+
PDO_upload : 1,
279+
SDO_complete_access : 1,
280+
unused : 2;
275281
uint8_t FoE_details;
276282
uint8_t EoE_details;
277283
uint8_t SoE_channels;
278284
uint8_t DS402_channels;
279285
uint8_t SysmanClass;
280286
uint8_t flags;
281-
int16_t current_on_ebus;
287+
int16_t current_on_ebus; // mA, negative means feeding current
282288
uint8_t group_info_id_dup;
283289
uint8_t reserved_B;
284-
uint16_t physical_port;
290+
uint16_t port_0 : 4,
291+
port_1 : 4,
292+
port_2 : 4,
293+
port_3 : 4;
285294
uint16_t physical_memory_address;
286295
uint8_t reserved_C[12];
287296
} __attribute__((__packed__));
@@ -344,12 +353,24 @@ namespace kickcat
344353
uint16_t index;
345354
uint8_t subindex;
346355
} __attribute__((__packed__));
356+
357+
/// ETG 1000.6
358+
struct Emergency
359+
{
360+
uint16_t number : 9,
361+
reserved : 3,
362+
service : 4; // i.e. request, response
363+
364+
uint16_t error_code;
365+
uint8_t error_register;
366+
uint8_t data[5];
367+
} __attribute__((__packed__));
347368
}
348369

349370
namespace CoE
350371
{
351-
constexpr uint16_t SM_COM_TYPE = 0x1C00; // each sub-entry described SM[x] com type (mailbox in/out, PDO in/out, not used)
352-
constexpr uint16_t SM_CHANNEL = 0x1C10; // each entry is associated with the mapped PDOs (if in used)
372+
constexpr uint16_t SM_COM_TYPE = 0x1C00; // each sub-entry described SM[x] com type (mailbox in/out, PDO in/out, not used)
373+
constexpr uint16_t SM_CHANNEL = 0x1C10; // each entry is associated with the mapped PDOs (if in used)
353374

354375
enum Service
355376
{

src/Bus.cc

+12-2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ namespace kickcat
7373
auto error_callback = [&](){ THROW_ERROR("init error while cleaning slaves mailboxes"); };
7474
checkMailboxes(error_callback);
7575
processMessages(error_callback);
76+
77+
// create CoE emergency reception callback
78+
for (auto& slave : slaves_)
79+
{
80+
if (slave.supported_mailbox & eeprom::MailboxProtocol::CoE)
81+
{
82+
auto emg = std::make_shared<EmergencyMessage>(slave.mailbox);
83+
slave.mailbox.to_process.push_back(emg);
84+
}
85+
}
7686
}
7787

7888

@@ -204,9 +214,9 @@ namespace kickcat
204214
size_t detected_slaves = slaves_.size();
205215
for (size_t i = 0; i < slaves_.size(); ++i)
206216
{
207-
auto process = [detected_slaves](DatagramHeader const*, uint8_t const*, uint16_t wkc)
217+
auto process = [](DatagramHeader const*, uint8_t const*, uint16_t wkc)
208218
{
209-
if (wkc != detected_slaves)
219+
if (wkc != 1)
210220
{
211221
return true;
212222
}

src/Mailbox.cc

+32
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ namespace kickcat
5353
it = to_process.erase(it);
5454
return true;
5555
}
56+
case ProcessingResult::FINALIZE_AND_KEEP:
57+
{
58+
return true;
59+
}
5660
default: { }
5761
}
5862
}
@@ -299,4 +303,32 @@ namespace kickcat
299303

300304
return ProcessingResult::FINALIZE;
301305
}
306+
307+
308+
EmergencyMessage::EmergencyMessage(Mailbox& mailbox)
309+
: AbstractMessage(mailbox.recv_size)
310+
, mailbox_{mailbox}
311+
{
312+
313+
}
314+
315+
ProcessingResult EmergencyMessage::process(uint8_t const* received)
316+
{
317+
mailbox::Header const* header = reinterpret_cast<mailbox::Header const*>(received);
318+
mailbox::Emergency const* emg = reinterpret_cast<mailbox::Emergency const*>(received + sizeof(mailbox::Header));
319+
320+
// check if the received message is an emergency one
321+
if (header->type != mailbox::Type::CoE)
322+
{
323+
return ProcessingResult::NOOP;
324+
}
325+
326+
if (emg->service != CoE::Service::EMERGENCY)
327+
{
328+
return ProcessingResult::NOOP;
329+
}
330+
331+
mailbox_.emergencies.push_back(*emg);
332+
return ProcessingResult::FINALIZE_AND_KEEP;
333+
}
302334
}

src/Slave.cc

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "Slave.h"
2+
#include "Error.h"
23

34
namespace kickcat
45
{
@@ -90,7 +91,7 @@ namespace kickcat
9091
}
9192
case eeprom::Category::DataTypes:
9293
{
93-
printf("DataTypes!\n");
94+
DEBUG_PRINT("DataTypes!\n");
9495
break;
9596
}
9697
case eeprom::Category::General:
@@ -120,7 +121,7 @@ namespace kickcat
120121
}
121122
case eeprom::Category::DC:
122123
{
123-
printf("DC!\n");
124+
DEBUG_PRINT("DC!\n");
124125
break;
125126
}
126127
case eeprom::Category::End:

src/protocol.cc

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace kickcat
3030
case 0x06090030: { return "Value range of parameter exceeded"; }
3131
case 0x06090031: { return "Value of parameter written too high"; }
3232
case 0x06090032: { return "Value of parameter written too low"; }
33+
case 0x06090033: { return "Configured module list does not match detected module list"; }
3334
case 0x06090036: { return "Maximum value is less than minimum value"; }
3435
case 0x08000000: { return "General error"; }
3536
case 0x08000020: { return "Data cannot be transferred or stored to the application"; }

0 commit comments

Comments
 (0)