Skip to content

Commit 39b624b

Browse files
authored
Separate RPDO/TPDO data links and fixed SDO macro (#128)
## Separate RPDO/TPDO data links and fixed SDO macro Separates out the RPDO and TPDO data links to not point to the same entries in the object dictionary. This also fixes the flags on the SDO server macro to allow it to function correctly. ## Integration Instructions: 1. For any DATA_LINK_START_KEY_21XX and DATA_LINK_21XX macro, replace the PDO_NUMBER field with the new LINK_RPDO_NUMBER or LINK_TPDO_NUMBER macro to link to the respective RPDO or TPDO mapping entry. Refer to `samples/canopen/canopen_rpdo/RPDOCanNode.hpp` and `samples/canopen/canopen_tpdo/TPDOCanNode.hpp` for examples. 2. If you need a variable accessible to both an RPDO and TPDO, duplicate the DATA_LINK_21XX entry for the variable in the corresponding DATA_LINK_START_KEY_21XX for the given RPDO/TPDO with the related LINK_RPDO_NUMBER or LINK_TPDO_NUMBER macro. --------- Co-authored-by: GitHub Build <N/A>
1 parent d02a9bd commit 39b624b

6 files changed

Lines changed: 55 additions & 37 deletions

File tree

include/core/io/CANOpenMacros.hpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,12 @@
121121
}, \
122122
{ \
123123
/* SDO Server Request COBID */ \
124-
.Key = CO_KEY(0x1200, 0x01, CO_OBJ__N__R_), \
124+
.Key = CO_KEY(0x1200, 0x01, CO_OBJ_DN__R_), \
125125
.Type = CO_TUNSIGNED32, \
126126
.Data = (CO_DATA) CO_COBID_SDO_REQUEST(), \
127127
}, \
128128
{ /* SDO Server Response COBID */ \
129-
.Key = CO_KEY(0x1200, 0x02, CO_OBJ__N__R_), \
129+
.Key = CO_KEY(0x1200, 0x02, CO_OBJ_DN__R_), \
130130
.Type = CO_TUNSIGNED32, \
131131
.Data = (CO_DATA) CO_COBID_SDO_RESPONSE(), \
132132
}
@@ -199,7 +199,7 @@
199199
{ \
200200
.Key = CO_KEY(0x1600 + RPDO_NUMBER, SUB_INDEX, CO_OBJ_D___R_), \
201201
.Type = CO_TUNSIGNED32, \
202-
.Data = (CO_DATA) CO_LINK(0x2100 + RPDO_NUMBER, 0x00 + SUB_INDEX, DATA_SIZE), \
202+
.Data = (CO_DATA) CO_LINK(0x2200 + RPDO_NUMBER, 0x00 + SUB_INDEX, DATA_SIZE), \
203203
}
204204

205205
/**
@@ -288,12 +288,12 @@
288288
* on the PDO number that it is associated with, this macro takes the PDO number associated with the
289289
* data that will be linked.
290290
*
291-
* @param PDO_NUMBER (integer) the PDO number that this data link section is associated with.
291+
* @param LINK_NUMBER (integer) the link number that this data link section is associated with.
292292
* @param NUMBER_OF_SUB_INDICES (integer) the number of links that this section will include.
293293
*/
294-
#define DATA_LINK_START_KEY_21XX(PDO_NUMBER, NUMBER_OF_SUB_INDICES) \
294+
#define DATA_LINK_START_KEY_21XX(LINK_NUMBER, NUMBER_OF_SUB_INDICES) \
295295
{ \
296-
.Key = CO_KEY(0x2100 + PDO_NUMBER, 0, CO_OBJ_D___R_), \
296+
.Key = CO_KEY(0x2100 + LINK_NUMBER, 0, CO_OBJ_D___R_), \
297297
.Type = CO_TUNSIGNED8, \
298298
.Data = (CO_DATA) NUMBER_OF_SUB_INDICES, \
299299
}
@@ -305,19 +305,34 @@
305305
* to allow for both TPDOs and RPDOs of any number to be linked as well as any data type and
306306
* any data pointers.
307307
*
308-
* @param PDO_NUMBER (integer) the PDO number that this data link is associated with
308+
* @param LINK_NUMBER (integer) the link number that this data link is associated with
309309
* @param SUB_INDEX (integer) the sub index in the great Data Link section.
310310
* @param DATA_TYPE (CO_T...) type of the data that is being linked too. You should use the CANOpen definitions for
311311
* types here.
312312
* @param DATA_POINTER (pointer) a pointer to a piece of data that this data link will connect to. Please provide this
313313
* as a pointer using the &variableName syntax. This macro does not automatically add the &
314314
*/
315-
#define DATA_LINK_21XX(PDO_NUMBER, SUB_INDEX, DATA_TYPE, DATA_POINTER) \
315+
#define DATA_LINK_21XX(LINK_NUMBER, SUB_INDEX, DATA_TYPE, DATA_POINTER) \
316316
{ \
317-
.Key = CO_KEY(0x2100 + PDO_NUMBER, SUB_INDEX, CO_OBJ____PRW), \
317+
.Key = CO_KEY(0x2100 + LINK_NUMBER, SUB_INDEX, CO_OBJ____PRW), \
318318
.Type = DATA_TYPE, \
319319
.Data = (CO_DATA) DATA_POINTER, \
320320
}
321+
322+
/**
323+
* This macro converts a TPDO number to the corresponding Link number. ONLY USE FOR THE DATA_LINK!
324+
*
325+
* @param PDO_NUMBER (integer) the PDO number for the data link
326+
*/
327+
#define LINK_TPDO_NUMBER(PDO_NUMBER) (PDO_NUMBER)
328+
329+
/**
330+
* This macro converts a RPDO number to the corresponding Link number. ONLY USE FOR THE DATA_LINK!
331+
*
332+
* @param PDO_NUMBER (integer) the PDO number for the data link
333+
*/
334+
#define LINK_RPDO_NUMBER(PDO_NUMBER) (PDO_NUMBER + 0x100)
335+
321336
// clang-format on
322337

323338
#endif // EVT_CANOPENMACROS_HPP

samples/canopen/canopen_rpdo/RPDOCanNode.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ class RPDOCanNode : public CANDevice {
109109

110110
// User defined data, this will be where we put elements that can be
111111
// accessed via SDO and depending on configuration PDO
112-
DATA_LINK_START_KEY_21XX(0, 2),
113-
DATA_LINK_21XX(0, 1, CO_TUNSIGNED8, &sampleDataA),
114-
DATA_LINK_21XX(0, 2, CO_TUNSIGNED16, &sampleDataB),
112+
DATA_LINK_START_KEY_21XX(LINK_RPDO_NUMBER(0), 2),
113+
DATA_LINK_21XX(LINK_RPDO_NUMBER(0), 1, CO_TUNSIGNED8, &sampleDataA),
114+
DATA_LINK_21XX(LINK_RPDO_NUMBER(0), 2, CO_TUNSIGNED16, &sampleDataB),
115115

116116
// End of dictionary marker
117117
CO_OBJ_DICT_ENDMARK,

samples/canopen/canopen_rpdo/main.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ namespace time = core::time;
2525
// aside CANopen messages into a specific queue
2626
///////////////////////////////////////////////////////////////////////////////
2727

28+
io::UART* uart;
29+
2830
/**
2931
* Interrupt handler to get CAN messages. A function pointer to this function
3032
* will be passed to the EVT-core CAN interface which will in turn call this
@@ -36,20 +38,18 @@ namespace time = core::time;
3638
* @param message[in] The passed in CAN message that was read.
3739
*/
3840

39-
io::UART& uart = io::getUART<io::Pin::UART_TX, io::Pin::UART_RX>(9600);
40-
4141
// create a can interrupt handler
4242
void canInterrupt(io::CANMessage& message, void* priv) {
4343
auto* queue = (core::types::FixedQueue<CANOPEN_QUEUE_SIZE, io::CANMessage>*) priv;
4444

4545
// print out raw received data
46-
uart.printf("Got RAW message from %X of length %d with data: ", message.getId(), message.getDataLength());
46+
uart->printf("Got RAW message from %X of length %d with data: ", message.getId(), message.getDataLength());
4747
uint8_t* data = message.getPayload();
4848
for (int i = 0; i < message.getDataLength(); i++) {
49-
uart.printf("%X ", *data);
49+
uart->printf("%X ", *data);
5050
data++;
5151
}
52-
uart.printf("\r\n");
52+
uart->printf("\r\n");
5353

5454
if (queue != nullptr)
5555
queue->append(message);
@@ -59,6 +59,7 @@ int main() {
5959
// Initialize system
6060
core::platform::init();
6161

62+
uart = &io::getUART<io::Pin::UART_TX, io::Pin::UART_RX>(9600);
6263
// Initialize the timer
6364
dev::Timer& timer = dev::getTimer<dev::MCUTimer::Timer2>(100);
6465

@@ -98,7 +99,7 @@ int main() {
9899

99100
// test that the board is connected to the can network
100101
if (result != io::CAN::CANStatus::OK) {
101-
uart.printf("Failed to connect to CAN network\r\n");
102+
uart->printf("Failed to connect to CAN network\r\n");
102103
return 1;
103104
}
104105

@@ -114,7 +115,7 @@ int main() {
114115
time::wait(500);
115116

116117
// print any CANopen errors
117-
uart.printf("Error: %d\r\n", CONodeGetErr(&canNode));
118+
uart->printf("Error: %d\r\n", CONodeGetErr(&canNode));
118119

119120
///////////////////////////////////////////////////////////////////////////
120121
// Main loop
@@ -127,11 +128,11 @@ int main() {
127128
if (lastVal1 != testCanNode.getSampleDataA() || lastVal2 != testCanNode.getSampleDataB()) {
128129
lastVal1 = testCanNode.getSampleDataA();
129130
lastVal2 = testCanNode.getSampleDataB();
130-
uart.printf("Current value: %X, %X\r\n", lastVal1, lastVal2);
131+
uart->printf("Current value: %X, %X\r\n", lastVal1, lastVal2);
131132
}
132133

133134
io::processCANopenNode(&canNode);
134135
// Wait for new data to come in
135-
time::wait(10);
136+
time::wait(1);
136137
}
137138
}

samples/canopen/canopen_sample/TestCanNode.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ class TestCanNode : public CANDevice {
9191
TRANSMIT_PDO_MAPPING_START_KEY_1AXX(0, 1),
9292
TRANSMIT_PDO_MAPPING_ENTRY_1AXX(0, 0x01, PDO_MAPPING_UNSIGNED8),
9393

94-
DATA_LINK_START_KEY_21XX(0, 1),
95-
DATA_LINK_21XX(0, 1, CO_TUNSIGNED8, &sampleData),
94+
DATA_LINK_START_KEY_21XX(LINK_TPDO_NUMBER(0), 1),
95+
DATA_LINK_21XX(LINK_TPDO_NUMBER(0), 1, CO_TUNSIGNED8, &sampleData),
9696

9797
// End of dictionary marker
9898
CO_OBJ_DICT_ENDMARK,

samples/canopen/canopen_tpdo/TPDOCanNode.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ class TPDOCanNode : public CANDevice {
106106

107107
// User defined data, this will be where we put elements that can be
108108
// accessed via SDO and depending on configuration PDO
109-
DATA_LINK_START_KEY_21XX(0, 0x02),
110-
DATA_LINK_21XX(0x00, 0x01, CO_TUNSIGNED8, &sampleDataA),
111-
DATA_LINK_21XX(0x00, 0x02, CO_TUNSIGNED16, &sampleDataB),
109+
DATA_LINK_START_KEY_21XX(LINK_TPDO_NUMBER(0), 0x02),
110+
DATA_LINK_21XX(LINK_TPDO_NUMBER(0), 0x01, CO_TUNSIGNED8, &sampleDataA),
111+
DATA_LINK_21XX(LINK_TPDO_NUMBER(0), 0x02, CO_TUNSIGNED16, &sampleDataB),
112112

113113
// End of dictionary marker
114114
CO_OBJ_DICT_ENDMARK,

samples/canopen/canopen_tpdo/main.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ namespace time = core::time;
2323
// aside CANopen messages into a specific queue
2424
///////////////////////////////////////////////////////////////////////////////
2525

26+
io::UART* uart;
27+
2628
/**
2729
* Interrupt handler to get CAN messages. A function pointer to this function
2830
* will be passed to the EVT-core CAN interface which will in turn call this
@@ -34,34 +36,32 @@ namespace time = core::time;
3436
* @param message[in] The passed in CAN message that was read.
3537
*/
3638

37-
io::UART& uart = io::getUART<io::Pin::UART_TX, io::Pin::UART_RX>(9600);
38-
3939
// create a can interrupt handler
4040
void canInterrupt(io::CANMessage& message, void* priv) {
4141
auto* queue = (core::types::FixedQueue<CANOPEN_QUEUE_SIZE, io::CANMessage>*) priv;
4242

4343
// print out raw received data
44-
uart.printf("Got RAW message from %X of length %d with data: ", message.getId(), message.getDataLength());
44+
uart->printf("Got RAW message from %X of length %d with data: ", message.getId(), message.getDataLength());
4545
uint8_t* data = message.getPayload();
4646
for (int i = 0; i < message.getDataLength(); i++) {
47-
uart.printf("%X ", *data);
47+
uart->printf("%X ", *data);
4848
data++;
4949
}
50-
uart.printf("\r\n");
50+
uart->printf("\r\n");
5151

5252
if (queue != nullptr)
5353
queue->append(message);
5454
}
5555

5656
// setup a TPDO event handler to print the raw TPDO message when sending
5757
extern "C" void COPdoTransmit(CO_IF_FRM* frm) {
58-
uart.printf("Sending PDO as 0x%X with length %d and data: ", frm->Identifier, frm->DLC);
58+
uart->printf("Sending PDO as 0x%X with length %d and data: ", frm->Identifier, frm->DLC);
5959
uint8_t* data = frm->Data;
6060
for (int i = 0; i < frm->DLC; i++) {
61-
uart.printf("%X ", *data);
61+
uart->printf("%X ", *data);
6262
data++;
6363
}
64-
uart.printf("\r\n");
64+
uart->printf("\r\n");
6565
}
6666

6767
int main() {
@@ -71,6 +71,8 @@ int main() {
7171
// create the TPDO node
7272
TPDOCanNode testCanNode;
7373

74+
uart = &io::getUART<io::Pin::UART_TX, io::Pin::UART_RX>(9600);
75+
7476
// Initialize the timer
7577
dev::Timer& timer = dev::getTimer<dev::MCUTimer::Timer2>(100);
7678

@@ -106,7 +108,7 @@ int main() {
106108

107109
// test that the board is connected to the can network
108110
if (result != io::CAN::CANStatus::OK) {
109-
uart.printf("Failed to connect to CAN network\r\n");
111+
uart->printf("Failed to connect to CAN network\r\n");
110112
return 1;
111113
}
112114

@@ -122,7 +124,7 @@ int main() {
122124
time::wait(500);
123125

124126
// print any CANopen errors
125-
uart.printf("Error: %d\r\n", CONodeGetErr(&canNode));
127+
uart->printf("Error: %d\r\n", CONodeGetErr(&canNode));
126128

127129
///////////////////////////////////////////////////////////////////////////
128130
// Main loop
@@ -136,7 +138,7 @@ int main() {
136138
if (lastVal1 != testCanNode.getSampleDataA() || lastVal2 != testCanNode.getSampleDataB()) {
137139
lastVal1 = testCanNode.getSampleDataA();
138140
lastVal2 = testCanNode.getSampleDataB();
139-
uart.printf("Current value: %X, %X\r\n", lastVal1, lastVal2);
141+
uart->printf("Current value: %X, %X\r\n", lastVal1, lastVal2);
140142
}
141143

142144
io::processCANopenNode(&canNode);

0 commit comments

Comments
 (0)