Skip to content

Commit 6ee0e8c

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 d78cccc commit 6ee0e8c

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
@@ -140,6 +140,8 @@ static uint32_t co_pdo_mapping_validate (co_pdo_t * pdo, uint8_t number_of_mappi
140140
if (IS_CYCLIC (pdo->sync_start))
141141
pdo->sync_wait = true;
142142

143+
pdo->rpdo_monitoring = false;
144+
143145
return 0;
144146
}
145147

@@ -553,6 +555,7 @@ static void co_pdo_transmit (co_net_t * net, co_pdo_t * pdo)
553555
int co_pdo_timer (co_net_t * net, os_tick_t now)
554556
{
555557
unsigned int ix;
558+
bool rpdo_timeout = false;
556559

557560
if (net->state != STATE_OP)
558561
return -1;
@@ -575,6 +578,37 @@ int co_pdo_timer (co_net_t * net, os_tick_t now)
575578
}
576579
}
577580

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

@@ -797,6 +831,13 @@ void co_pdo_rx (co_net_t * net, uint32_t id, void * msg, size_t dlc)
797831
memcpy (&pdo->frame, msg, dlc);
798832
pdo->timestamp = os_tick_current();
799833

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

0 commit comments

Comments
 (0)