Skip to content

Commit 3a7d448

Browse files
committed
Add RPDO deadline monitoring
As described in CiA 301, Object 1400h to 15FFh: RPDO communication parameter, Subindex 05h. The indication to the application is done via the EMCY callback. The EMCY transmission is not described, but since there is an EMCY code defined for RPDO timeout, it's assumed to be meant for this purpose. Change-Id: Ie98f67fb20b615d56fdbdfc207b38bfeef6d4fb6
1 parent a0e054e commit 3a7d448

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

src/co_emcy.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ void co_emcy_handle_can_state (co_net_t * net)
384384
if (
385385
!net->emcy.state.overrun && !net->emcy.state.error_passive &&
386386
!net->emcy.state.bus_off && !net->emcy.node_guard_error &&
387-
!net->emcy.heartbeat_error)
387+
!net->emcy.heartbeat_error && !net->emcy.rpdo_timeout)
388388
{
389389
co_emcy_error_register_clear (net, CO_ERR_COMMUNICATION);
390390
}

src/co_main.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ typedef struct co_pdo
8282
{
8383
bool queued : 1;
8484
bool sync_wait : 1;
85+
bool rpdo_monitoring : 1;
86+
bool rpdo_timeout : 1;
8587
};
8688
uint32_t mappings[MAX_PDO_ENTRIES];
8789
const co_obj_t * objs[MAX_PDO_ENTRIES];
@@ -220,6 +222,7 @@ typedef struct co_emcy
220222
os_channel_state_t state; /**< CAN state */
221223
bool node_guard_error; /**< Node guard error */
222224
bool heartbeat_error; /**< Heartbeat error */
225+
bool rpdo_timeout; /**< RPDO timeout */
223226
uint32_t cobids[MAX_EMCY_COBIDS]; /**< EMCY consumer object */
224227
} co_emcy_t;
225228

src/co_pdo.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ static uint32_t co_pdo_mapping_validate (co_pdo_t * pdo, uint8_t number_of_mappi
142142
if (IS_CYCLIC (pdo->sync_start))
143143
pdo->sync_wait = true;
144144

145+
pdo->rpdo_monitoring = false;
146+
145147
return 0;
146148
}
147149

@@ -555,6 +557,7 @@ static void co_pdo_transmit (co_net_t * net, co_pdo_t * pdo)
555557
int co_pdo_timer (co_net_t * net, os_tick_t now)
556558
{
557559
unsigned int ix;
560+
bool rpdo_timeout = false;
558561

559562
if (net->state != STATE_OP)
560563
return -1;
@@ -577,6 +580,37 @@ int co_pdo_timer (co_net_t * net, os_tick_t now)
577580
}
578581
}
579582

583+
/* Check for RPDOs with event timer (deadline monitoring) */
584+
for (ix = 0; ix < MAX_RX_PDO; ix++)
585+
{
586+
co_pdo_t * pdo = &net->pdo_rx[ix];
587+
588+
if (pdo->cobid & CO_COBID_INVALID)
589+
continue;
590+
591+
if (pdo->rpdo_timeout)
592+
{
593+
/* Already signaled, just track the combined state. */
594+
rpdo_timeout = true;
595+
continue;
596+
}
597+
598+
if (!pdo->rpdo_monitoring || pdo->event_timer == 0)
599+
continue;
600+
601+
if (co_is_expired (now, pdo->timestamp, 1000 * pdo->event_timer))
602+
{
603+
/* Deadline timeout elapsed, transmit EMCY */
604+
pdo->rpdo_monitoring = false;
605+
pdo->rpdo_timeout = rpdo_timeout = true;
606+
co_emcy_error_register_set (net, CO_ERR_COMMUNICATION);
607+
co_emcy_tx (net, 0x8250, 0, NULL);
608+
}
609+
}
610+
611+
/* Update RPDO timeout state */
612+
net->emcy.rpdo_timeout = rpdo_timeout;
613+
580614
return 0;
581615
}
582616

@@ -799,6 +833,13 @@ void co_pdo_rx (co_net_t * net, uint32_t id, void * msg, size_t dlc)
799833
memcpy (&pdo->frame, msg, dlc);
800834
pdo->timestamp = os_tick_current();
801835

836+
if (pdo->event_timer > 0)
837+
{
838+
/* Arm RPDO deadline monitoring */
839+
pdo->rpdo_monitoring = true;
840+
pdo->rpdo_timeout = false;
841+
}
842+
802843
if (IS_EVENT (pdo->transmission_type))
803844
{
804845
/* Deliver event-driven RPDOs asynchronously */

0 commit comments

Comments
 (0)