Skip to content

Commit 3a15d72

Browse files
authored
Merge pull request #14 from arduino/fix-can-filter
[x8h7_can] Fix extended CAN ID when configuring can filter (and use the same struct in both firmware and linux driver)
2 parents 4f6f738 + f4d778e commit 3a15d72

File tree

2 files changed

+87
-61
lines changed

2 files changed

+87
-61
lines changed

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

Lines changed: 86 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,25 @@ RX1IE: Receive Buffer 1 Full I questo non serve
7878
#define AFTER_SUSPEND_POWER 4
7979
#define AFTER_SUSPEND_RESTART 8
8080

81-
#define X8H7_FLT_EXT 0x80000000
8281
#define X8H7_STD_FLT_MAX 128
8382
#define X8H7_EXT_FLT_MAX 64
8483

8584
/**
8685
*/
87-
struct x8h7_can_filter {
88-
u32 id;
89-
u32 mask;
86+
union x8h7_can_filter_message
87+
{
88+
struct __attribute__((packed))
89+
{
90+
uint32_t idx;
91+
uint32_t id;
92+
uint32_t mask;
93+
} field;
94+
uint8_t buf[sizeof(uint32_t) /* idx */ + sizeof(uint32_t) /* id */ + sizeof(uint32_t) /* mask */];
9095
};
9196

92-
union x8h7_can_message
97+
/**
98+
*/
99+
union x8h7_can_frame_message
93100
{
94101
struct __attribute__((packed))
95102
{
@@ -123,8 +130,9 @@ struct x8h7_can_priv {
123130
int after_suspend;
124131
int restart_tx;
125132

126-
struct x8h7_can_filter std_flt[X8H7_STD_FLT_MAX];
127-
struct x8h7_can_filter ext_flt[X8H7_EXT_FLT_MAX];
133+
struct can_filter std_flt[X8H7_STD_FLT_MAX];
134+
struct can_filter ext_flt[X8H7_EXT_FLT_MAX];
135+
128136
struct mutex lock;
129137
};
130138

@@ -274,7 +282,7 @@ static void x8h7_can_hook(void *arg, x8h7_pkt_t *pkt)
274282
} else {
275283
struct sk_buff *skb;
276284
struct can_frame *frame;
277-
union x8h7_can_message x8h7_can_msg;
285+
union x8h7_can_frame_message x8h7_can_msg;
278286

279287
skb = alloc_can_skb(priv->net, &frame);
280288
if (!skb) {
@@ -286,7 +294,7 @@ static void x8h7_can_hook(void *arg, x8h7_pkt_t *pkt)
286294
/* Copy header from raw byte-stream onto union. */
287295
memcpy(x8h7_can_msg.buf, pkt->data, X8H7_CAN_HEADER_SIZE);
288296

289-
/* Extract can_id and can_dlc. Note: x8h7_can_message uses the exact
297+
/* Extract can_id and can_dlc. Note: x8h7_can_frame_message uses the exact
290298
* same flags for signaling extended/standard id mode or remote
291299
* retransmit request as struct can_frame.
292300
*/
@@ -522,7 +530,12 @@ static void x8h7_can_hw_rx(struct x8h7_can_priv *priv)
522530
*/
523531
static void x8h7_can_hw_tx(struct x8h7_can_priv *priv, struct can_frame *frame)
524532
{
525-
union x8h7_can_message x8h7_can_msg;
533+
union x8h7_can_frame_message x8h7_can_msg;
534+
#ifdef DEBUG
535+
char data_str[X8H7_CAN_FRAME_MAX_DATA_LEN * 4];
536+
int i;
537+
int len;
538+
#endif
526539

527540
DBG_PRINT("\n");
528541

@@ -535,14 +548,12 @@ static void x8h7_can_hw_tx(struct x8h7_can_priv *priv, struct can_frame *frame)
535548
memcpy(x8h7_can_msg.field.data, frame->data, x8h7_can_msg.field.len);
536549

537550
#ifdef DEBUG
538-
char data_str[X8H7_CAN_FRAME_MAX_DATA_LEN * 4] = {0};
539-
int i = 0, len = 0;
540-
541-
for (i = 0; (i < frame->can_dlc) && (len < sizeof(data_str)); i++)
551+
i = 0; len = 0;
552+
for (i = 0; (i < x8h7_can_msg.field.len) && (len < sizeof(data_str)); i++)
542553
{
543-
len += snprintf(data_str + len, sizeof(data_str) - len, " %02X", can_msg.field.data[i]);
554+
len += snprintf(data_str + len, sizeof(data_str) - len, " %02X", x8h7_can_msg.field.data[i]);
544555
}
545-
DBG_PRINT("Send CAN frame to H7: id = %08X, len = %d, data = [%s ]\n", can_msg.field.id, can_msg.field.len, data_str);
556+
DBG_PRINT("Send CAN frame to H7: id = %08X, len = %d, data = [%s ]\n", x8h7_can_msg.field.id, x8h7_can_msg.field.len, data_str);
546557
#endif
547558

548559
x8h7_pkt_enq(priv->periph,
@@ -783,46 +794,20 @@ static const struct net_device_ops x8h7_can_netdev_ops = {
783794

784795
/**
785796
*/
786-
static int x8h7_can_config_filter(struct x8h7_can_priv *priv,
787-
const char *buf, int type)
797+
static int x8h7_can_hw_config_filter(struct x8h7_can_priv *priv,
798+
uint32_t const idx,
799+
uint32_t const id,
800+
uint32_t const mask)
788801
{
789-
u32 idx;
790-
u32 id;
791-
u32 mask;
792-
int ret;
793-
u32 data[3];
802+
union x8h7_can_filter_message x8h7_msg;
794803

795-
ret = sscanf(buf, "%x %x %x", &idx, &id, &mask);
796-
if (ret != 3) {
797-
DBG_ERROR("invalid num of params\n");
798-
return -1;
799-
}
800-
801-
if (type == 0) {
802-
if ((idx >= X8H7_STD_FLT_MAX) ||
803-
(id & ~0x7FF) || (mask & ~0x7FF)) {
804-
DBG_ERROR("invalid params\n");
805-
return -1;
806-
}
807-
priv->std_flt[idx].id = id;
808-
priv->std_flt[idx].mask = mask;
809-
} else {
810-
if ((idx >= X8H7_EXT_FLT_MAX) ||
811-
(id & ~0x1FFFFFFF) || (mask & ~0x1FFFFFFF)) {
812-
DBG_ERROR("invalid params\n");
813-
return -1;
814-
}
815-
priv->ext_flt[idx].id = id;
816-
priv->ext_flt[idx].mask = mask;
817-
idx |= X8H7_FLT_EXT;
818-
}
804+
x8h7_msg.field.idx = idx;
805+
x8h7_msg.field.id = id;
806+
x8h7_msg.field.mask = mask;
819807

820808
DBG_PRINT("SEND idx %X, id %X, mask %X\n", idx, id, mask);
821809

822-
data[0] = idx;
823-
data[1] = id;
824-
data[2] = mask;
825-
x8h7_pkt_enq(priv->periph, X8H7_CAN_OC_FLT, sizeof(data), data);
810+
x8h7_pkt_enq(priv->periph, X8H7_CAN_OC_FLT, sizeof(x8h7_msg.buf), x8h7_msg.buf);
826811
x8h7_pkt_send();
827812

828813
return 0;
@@ -839,11 +824,12 @@ static ssize_t x8h7_can_sf_show(struct device *dev,
839824
int i;
840825

841826
len = 0;
842-
for (i=0; i<X8H7_STD_FLT_MAX; i++) {
843-
if (priv->std_flt[i].mask) {
827+
for (i = 0; i < X8H7_STD_FLT_MAX; i++)
828+
{
829+
if (priv->std_flt[i].can_mask) {
844830
len += snprintf(buf + len, PAGE_SIZE - len,
845831
"%02X %08X %08X\n",
846-
i, priv->std_flt[i].id, priv->std_flt[i].mask);
832+
i, priv->std_flt[i].can_id, priv->std_flt[i].can_mask);
847833
}
848834
}
849835
return len;
@@ -857,13 +843,33 @@ static ssize_t x8h7_can_sf_store(struct device *dev,
857843
const char *buf, size_t count)
858844
{
859845
struct x8h7_can_priv *priv = netdev_priv(to_net_dev(dev));
846+
uint32_t idx;
847+
uint32_t id;
848+
uint32_t mask;
860849
int ret;
861850

862-
ret = x8h7_can_config_filter(priv, buf, 0);
851+
ret = sscanf(buf, "%x %x %x", &idx, &id, &mask);
852+
853+
if (ret != 3) {
854+
DBG_ERROR("invalid num of params\n");
855+
return -EINVAL;
856+
}
857+
858+
if ((idx >= X8H7_STD_FLT_MAX) ||
859+
(id & ~0x7FF) || (mask & ~0x7FF)) {
860+
DBG_ERROR("invalid params\n");
861+
return -EINVAL;
862+
}
863+
864+
ret = x8h7_can_hw_config_filter(priv, idx, id, mask);
863865
if (ret) {
864866
DBG_ERROR("set filter\n");
865-
return -1;
867+
return -EIO;
866868
}
869+
870+
priv->std_flt[idx].can_id = id;
871+
priv->std_flt[idx].can_mask = mask;
872+
867873
return count;
868874
}
869875

@@ -880,10 +886,10 @@ static ssize_t x8h7_can_ef_show(struct device *dev,
880886
len = 0;
881887
for (i = 0; i < X8H7_EXT_FLT_MAX; i++)
882888
{
883-
if (priv->ext_flt[i].mask) {
889+
if (priv->ext_flt[i].can_mask) {
884890
len += snprintf(buf + len, PAGE_SIZE - len,
885891
"%02X %08X %08X\n",
886-
i, priv->ext_flt[i].id, priv->ext_flt[i].mask);
892+
i, priv->ext_flt[i].can_id, priv->ext_flt[i].can_mask);
887893
}
888894
}
889895
return len;
@@ -898,12 +904,32 @@ static ssize_t x8h7_can_ef_store(struct device *dev,
898904
{
899905
struct x8h7_can_priv *priv = netdev_priv(to_net_dev(dev));
900906
int ret;
907+
uint32_t idx;
908+
uint32_t id;
909+
uint32_t mask;
901910

902-
ret = x8h7_can_config_filter(priv, buf, 1);
911+
ret = sscanf(buf, "%x %x %x", &idx, &id, &mask);
912+
913+
if (ret != 3) {
914+
DBG_ERROR("invalid num of params\n");
915+
return -EINVAL;
916+
}
917+
918+
if ((idx >= X8H7_EXT_FLT_MAX) ||
919+
(id & ~0x1FFFFFFF) || (mask & ~0x1FFFFFFF)) {
920+
DBG_ERROR("invalid params\n");
921+
return -EINVAL;
922+
}
923+
924+
ret = x8h7_can_hw_config_filter(priv, idx, (CAN_EFF_FLAG | id), mask);
903925
if (ret) {
904926
DBG_ERROR("set filter\n");
905-
return -1;
927+
return -EIO;
906928
}
929+
930+
priv->ext_flt[idx].can_id = id;
931+
priv->ext_flt[idx].can_mask = mask;
932+
907933
return count;
908934
}
909935

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 = "665930e420b74c685a07bb05feb5a5677d8f1e65"
19+
SRCREV = "9aec9248a53b0bc1e0ea8a887da44a2bfc5c5bb5"
2020
PV = "0.0.2"
2121

2222
S = "${WORKDIR}/git"

0 commit comments

Comments
 (0)