Skip to content

Commit d052af3

Browse files
authored
Merge pull request #33 from nattgris/pdo-trigger
Make it possible to trigger only PDOs for a specific object
2 parents 3adaee4 + dc38946 commit d052af3

File tree

7 files changed

+153
-1
lines changed

7 files changed

+153
-1
lines changed

include/co_api.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,32 @@ CO_EXPORT void co_nmt (co_client_t * client, co_nmt_cmd_t cmd, uint8_t node);
394394
*/
395395
CO_EXPORT void co_sync (co_client_t * client);
396396

397+
/**
398+
* Trigger event-based PDOs
399+
*
400+
* This function triggers transmission of all event-based PDOs.
401+
*
402+
* @param client client handle
403+
*
404+
* @return 0 on success
405+
*/
406+
CO_EXPORT int co_pdo_event (co_client_t * client);
407+
408+
/**
409+
* Triggers event-based PDOs containing a specific object
410+
*
411+
* This function triggers transmission of all event-based PDOs
412+
* that map the specified object.
413+
*
414+
* @param client client handle
415+
* @param index index
416+
* @param subindex subindex
417+
*
418+
* @return 0 on success
419+
*/
420+
CO_EXPORT int co_pdo_obj_event (co_client_t * client, uint16_t index,
421+
uint8_t subindex);
422+
397423
/**
398424
* Read dictionary object entry
399425
*

src/co_main.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ void co_main (void * arg)
130130
co_handle_rx (net);
131131
break;
132132
case CO_JOB_PDO_EVENT:
133+
case CO_JOB_PDO_OBJ_EVENT:
133134
co_pdo_job (net, job);
134135
break;
135136
case CO_JOB_SDO_READ:
@@ -225,6 +226,21 @@ int co_pdo_event (co_client_t * client)
225226
return 0;
226227
}
227228

229+
int co_pdo_obj_event (co_client_t * client, uint16_t index, uint8_t subindex)
230+
{
231+
co_net_t * net = client->net;
232+
co_job_t * job = &client->job;
233+
234+
job->client = client;
235+
job->callback = NULL;
236+
job->type = CO_JOB_PDO_OBJ_EVENT;
237+
job->pdo.index = index;
238+
job->pdo.subindex = subindex;
239+
240+
os_mbox_post (net->mbox, job, OS_WAIT_FOREVER);
241+
return 0;
242+
}
243+
228244
int co_sdo_read (
229245
co_client_t * client,
230246
uint8_t node,

src/co_main.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ typedef enum co_job_type
9494
CO_JOB_PERIODIC,
9595
CO_JOB_RX,
9696
CO_JOB_PDO_EVENT,
97+
CO_JOB_PDO_OBJ_EVENT,
9798
CO_JOB_SDO_READ,
9899
CO_JOB_SDO_WRITE,
99100
CO_JOB_SDO_UPLOAD,
@@ -131,6 +132,13 @@ typedef struct co_emcy_job
131132
uint8_t value;
132133
} co_emcy_job_t;
133134

135+
/** Parameters for PDO job */
136+
typedef struct co_pdo_job
137+
{
138+
uint16_t index;
139+
uint8_t subindex;
140+
} co_pdo_job_t;
141+
134142
/** Generic job */
135143
typedef struct co_job
136144
{
@@ -139,6 +147,7 @@ typedef struct co_job
139147
{
140148
co_sdo_job_t sdo;
141149
co_emcy_job_t emcy;
150+
co_pdo_job_t pdo;
142151
};
143152
uint32_t timestamp;
144153
struct co_client * client;

src/co_pdo.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,52 @@ void co_pdo_trigger (co_net_t * net)
594594
}
595595
}
596596

597+
void co_pdo_trigger_with_obj (co_net_t * net, uint16_t index, uint8_t subindex)
598+
{
599+
unsigned int ix;
600+
uint8_t n;
601+
const co_obj_t * obj;
602+
const co_entry_t * entry;
603+
604+
/* Find mapped object */
605+
obj = co_obj_find (net, index);
606+
if (obj == NULL)
607+
return;
608+
609+
/* Find mapped entry */
610+
entry = co_entry_find (net, obj, subindex);
611+
if (entry == NULL)
612+
return;
613+
614+
/* Check that object is mappable */
615+
if ((entry->flags & OD_TPDO) == 0)
616+
return;
617+
618+
/* Transmit event-driven TPDOs, queue acyclic TPDOs */
619+
for (ix = 0; ix < MAX_TX_PDO; ix++)
620+
{
621+
co_pdo_t * pdo = &net->pdo_tx[ix];
622+
if (pdo->cobid & CO_COBID_INVALID)
623+
continue;
624+
625+
for (n = 0; n < pdo->number_of_mappings; n++)
626+
{
627+
if (pdo->entries[n] == entry)
628+
{
629+
if (IS_EVENT (pdo->transmission_type))
630+
{
631+
co_pdo_transmit (net, pdo);
632+
}
633+
else if (IS_ACYCLIC (pdo->transmission_type))
634+
{
635+
pdo->queued = true;
636+
}
637+
break;
638+
}
639+
}
640+
}
641+
}
642+
597643
int co_pdo_sync (co_net_t * net, uint8_t * msg, size_t dlc)
598644
{
599645
unsigned int ix;
@@ -761,6 +807,9 @@ void co_pdo_job (co_net_t * net, co_job_t * job)
761807
case CO_JOB_PDO_EVENT:
762808
co_pdo_trigger (net);
763809
break;
810+
case CO_JOB_PDO_OBJ_EVENT:
811+
co_pdo_trigger_with_obj (net, job->pdo.index, job->pdo.subindex);
812+
break;
764813
default:
765814
CC_ASSERT (0);
766815
}

src/co_pdo.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,20 @@ int co_pdo_timer (co_net_t * net, uint32_t now);
116116
*/
117117
void co_pdo_trigger (co_net_t * net);
118118

119+
/**
120+
* PDO trigger with object
121+
*
122+
* This function triggers an event on event-driven and acyclic
123+
* TPDOs that map the specified object. Event-driven TPDOs will be
124+
* transmitted immediately while acyclic TPDOs will be queued for
125+
* transmission at next SYNC.
126+
*
127+
* @param net network handle
128+
* @param index index
129+
* @param subindex subindex
130+
*/
131+
void co_pdo_trigger_with_obj (co_net_t * net, uint16_t index, uint8_t subindex);
132+
119133
/**
120134
* Start PDO job
121135
*

test/test_pdo.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,39 @@ TEST_F (PdoTest, TxAcyclic)
728728
EXPECT_EQ (0x181u, mock_os_channel_send_id);
729729
}
730730

731+
TEST_F (PdoTest, TriggerWithObj)
732+
{
733+
net.state = STATE_OP;
734+
735+
net.pdo_tx[0].transmission_type = 0xFF;
736+
net.pdo_tx[0].inhibit_time = 0;
737+
738+
// Should trigger PDO
739+
mock_co_obj_find_result = find_obj (0x6000);
740+
mock_co_entry_find_result = find_entry (mock_co_obj_find_result, 0);
741+
co_pdo_trigger_with_obj (&net, 0x6000, 0);
742+
EXPECT_EQ (0x1u, mock_os_channel_send_calls);
743+
744+
// Should not trigger PDO, not mapped
745+
mock_co_obj_find_result = find_obj (0x6001);
746+
mock_co_entry_find_result = find_entry (mock_co_obj_find_result, 0);
747+
co_pdo_trigger_with_obj (&net, 0x6001, 0);
748+
EXPECT_EQ (0x1u, mock_os_channel_send_calls);
749+
750+
// Should not trigger PDO, does not exist
751+
mock_co_obj_find_result = NULL;
752+
mock_co_entry_find_result = NULL;
753+
co_pdo_trigger_with_obj (&net, 0x6002, 0);
754+
EXPECT_EQ (0x1u, mock_os_channel_send_calls);
755+
756+
// Should not trigger PDO, invalid cob-id
757+
net.pdo_tx[0].cobid = CO_COBID_INVALID | 0x181;
758+
mock_co_obj_find_result = find_obj (0x6000);
759+
mock_co_entry_find_result = find_entry (mock_co_obj_find_result, 0);
760+
co_pdo_trigger_with_obj (&net, 0x6000, 0);
761+
EXPECT_EQ (0x1u, mock_os_channel_send_calls);
762+
}
763+
731764
TEST_F (PdoTest, SparsePdo)
732765
{
733766
const co_obj_t * obj1533 = find_obj (0x1533);

test/test_util.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ class TestBase : public ::testing::Test
128128
{0, OD_NOTIFY | OD_RO | OD_TPDO, DTYPE_UNSIGNED32, 32, 0, &value6000},
129129
};
130130

131+
const co_entry_t OD6001[1] = {
132+
{0, OD_NOTIFY | OD_RO | OD_TPDO, DTYPE_UNSIGNED32, 32, 1, NULL},
133+
};
134+
131135
uint16_t value6003_07;
132136
uint8_t value6003_08;
133137
uint32_t value6003_09;
@@ -159,7 +163,7 @@ class TestBase : public ::testing::Test
159163
{0, OD_RW | OD_RPDO, DTYPE_UNSIGNED32, 32, 0, &value7000},
160164
};
161165

162-
const co_obj_t test_od[36] = {
166+
const co_obj_t test_od[37] = {
163167
// clang-format off
164168
{0x1000, OTYPE_VAR, 0, OD1000, NULL},
165169
{0x1001, OTYPE_VAR, 0, OD1001, co_od1001_fn},
@@ -194,6 +198,7 @@ class TestBase : public ::testing::Test
194198
{0x2000, OTYPE_ARRAY, 8, OD2000, NULL},
195199
{0x2001, OTYPE_RECORD, 2, OD2001, cb2001},
196200
{0x6000, OTYPE_VAR, 0, OD6000, NULL},
201+
{0x6001, OTYPE_VAR, 0, OD6001, NULL},
197202
{0x6003, OTYPE_RECORD, 12, OD6003, NULL},
198203
{0x7000, OTYPE_VAR, 0, OD7000, NULL},
199204
{0, OTYPE_NULL, 0, NULL, NULL},

0 commit comments

Comments
 (0)