Skip to content

Commit 32e4ba3

Browse files
authored
Merge pull request #10 from arduino/fix-can-extended-id-rx
Fix: correctly pass-through received frames with both standard and extended CAN id
2 parents 07a2b33 + 17c8886 commit 32e4ba3

File tree

2 files changed

+38
-27
lines changed

2 files changed

+38
-27
lines changed

recipes-kernel/kernel-modules/x8h7/x8h7_can.c

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ RX1IE: Receive Buffer 1 Full I questo non serve
7070
#define X8H7_CAN_STS_FLG_EWARN 0x40 // Error Warning
7171
#define X8H7_CAN_STS_FLG_TX_OVR 0x80 // Transmit Buffer Overflow
7272

73-
#define CAN_FRAME_MAX_DATA_LEN 8
74-
#define X8H7_CAN_HEADER_SIZE 5
73+
#define X8H7_CAN_HEADER_SIZE 5
74+
#define X8H7_CAN_FRAME_MAX_DATA_LEN 8
7575

7676
#define AFTER_SUSPEND_UP 1
7777
#define AFTER_SUSPEND_DOWN 2
@@ -89,6 +89,17 @@ struct x8h7_can_filter {
8989
u32 mask;
9090
};
9191

92+
union x8h7_can_message
93+
{
94+
struct __attribute__((packed))
95+
{
96+
uint32_t id;
97+
uint8_t len;
98+
uint8_t data[X8H7_CAN_FRAME_MAX_DATA_LEN];
99+
} field;
100+
uint8_t buf[X8H7_CAN_HEADER_SIZE + X8H7_CAN_FRAME_MAX_DATA_LEN];
101+
};
102+
92103
/**
93104
*/
94105
struct x8h7_can_priv {
@@ -257,7 +268,7 @@ static void x8h7_can_hook(void *arg, x8h7_pkt_t *pkt)
257268

258269
switch(pkt->opcode) {
259270
case X8H7_CAN_OC_RECV:
260-
if (pkt->size < 5) {
271+
if (pkt->size < X8H7_CAN_HEADER_SIZE) {
261272
DBG_ERROR("received packed is too short (%d)\n", pkt->size);
262273
return;
263274
} else {
@@ -270,10 +281,19 @@ static void x8h7_can_hook(void *arg, x8h7_pkt_t *pkt)
270281
priv->net->stats.rx_dropped++;
271282
return;
272283
}
273-
frame->can_id = (pkt->data[3] << 24) | (pkt->data[2] << 16) |
274-
(pkt->data[1] << 8) | pkt->data[0];
275-
frame->can_dlc = get_can_dlc(pkt->data[4] & 0x0F);
276-
memcpy(frame->data, pkt->data + 5, frame->can_dlc);
284+
285+
/* Copy header from raw byte-stream onto union. */
286+
union x8h7_can_message x8h7_can_msg;
287+
memcpy(x8h7_can_msg.buf, pkt->data, X8H7_CAN_HEADER_SIZE);
288+
289+
/* Extract can_id and can_dlc. Note: x8h7_can_message uses the exact
290+
* same flags for signaling extended/standard id mode or remote
291+
* retransmit request as struct can_frame.
292+
*/
293+
frame->can_id = x8h7_can_msg.field.id;
294+
frame->can_dlc = x8h7_can_msg.field.len;
295+
memcpy(frame->data, pkt->data + X8H7_CAN_HEADER_SIZE, frame->can_dlc);
296+
277297
priv->net->stats.rx_packets++;
278298
priv->net->stats.rx_bytes += frame->can_dlc;
279299
can_led_event(priv->net, CAN_LED_EVENT_RX);
@@ -502,29 +522,20 @@ static void x8h7_can_hw_rx(struct x8h7_can_priv *priv)
502522
*/
503523
static void x8h7_can_hw_tx(struct x8h7_can_priv *priv, struct can_frame *frame)
504524
{
505-
union
506-
{
507-
struct __attribute__((packed))
508-
{
509-
uint32_t id; // 29 bit identifier
510-
uint8_t len; // Length of data field in bytes
511-
uint8_t data[CAN_FRAME_MAX_DATA_LEN]; // Data field
512-
} field;
513-
uint8_t buf[X8H7_CAN_HEADER_SIZE + CAN_FRAME_MAX_DATA_LEN];
514-
} can_msg;
525+
union x8h7_can_message x8h7_can_msg;
515526

516527
DBG_PRINT("\n");
517528

518529
if (frame->can_id & CAN_EFF_FLAG)
519-
can_msg.field.id = CAN_EFF_FLAG | (frame->can_id & CAN_EFF_MASK);
530+
x8h7_can_msg.field.id = CAN_EFF_FLAG | (frame->can_id & CAN_EFF_MASK);
520531
else
521-
can_msg.field.id = (frame->can_id & CAN_SFF_MASK);
532+
x8h7_can_msg.field.id = (frame->can_id & CAN_SFF_MASK);
522533

523-
can_msg.field.len = (frame->can_dlc <= CAN_FRAME_MAX_DATA_LEN) ? frame->can_dlc : CAN_FRAME_MAX_DATA_LEN;
524-
memcpy(can_msg.field.data, frame->data, can_msg.field.len);
534+
x8h7_can_msg.field.len = (frame->can_dlc <= X8H7_CAN_FRAME_MAX_DATA_LEN) ? frame->can_dlc : X8H7_CAN_FRAME_MAX_DATA_LEN;
535+
memcpy(x8h7_can_msg.field.data, frame->data, x8h7_can_msg.field.len);
525536

526537
#ifdef DEBUG
527-
char data_str[CAN_FRAME_MAX_DATA_LEN * 4] = {0};
538+
char data_str[X8H7_CAN_FRAME_MAX_DATA_LEN * 4] = {0};
528539
int i = 0, len = 0;
529540

530541
for (i = 0; (i < frame->can_dlc) && (len < sizeof(data_str)); i++)
@@ -534,8 +545,8 @@ static void x8h7_can_hw_tx(struct x8h7_can_priv *priv, struct can_frame *frame)
534545
DBG_PRINT("Send CAN frame to H7: id = %08X, len = %d, data = [%s ]\n", can_msg.field.id, can_msg.field.len, data_str);
535546
#endif
536547

537-
uint16_t const bytes_to_send = X8H7_CAN_HEADER_SIZE + can_msg.field.len; /* Send 4-Byte ID, 1-Byte Length and the required number of data bytes. */
538-
x8h7_pkt_enq(priv->periph, X8H7_CAN_OC_SEND, bytes_to_send, can_msg.buf);
548+
uint16_t const bytes_to_send = X8H7_CAN_HEADER_SIZE + x8h7_can_msg.field.len; /* Send 4-Byte ID, 1-Byte Length and the required number of data bytes. */
549+
x8h7_pkt_enq(priv->periph, X8H7_CAN_OC_SEND, bytes_to_send, x8h7_can_msg.buf);
539550
x8h7_pkt_send();
540551
}
541552

@@ -557,8 +568,8 @@ static void x8h7_can_tx_work_handler(struct work_struct *ws)
557568
DBG_PRINT("Send frame\n");
558569
frame = (struct can_frame *)priv->tx_skb->data;
559570

560-
if (frame->can_dlc > CAN_FRAME_MAX_DATA_LEN) {
561-
frame->can_dlc = CAN_FRAME_MAX_DATA_LEN;
571+
if (frame->can_dlc > X8H7_CAN_FRAME_MAX_DATA_LEN) {
572+
frame->can_dlc = X8H7_CAN_FRAME_MAX_DATA_LEN;
562573
}
563574

564575
x8h7_can_hw_tx(priv, frame);

recipes-kernel/linux-firmware/linux-firmware-arduino-portenta-x8-stm32h7_git.bb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ SRC_URI = " \
1616
file://monitor-m4-elf-file.path \
1717
file://monitor-m4-elf-file.service \
1818
"
19-
SRCREV = "96bcacb22b87f6f9169d1d01d531a4de641a3d63"
19+
SRCREV = "665930e420b74c685a07bb05feb5a5677d8f1e65"
2020
PV = "0.0.2"
2121

2222
S = "${WORKDIR}/git"

0 commit comments

Comments
 (0)