RK3588通过SPI外扩CAN【MCP2518FD】
需要4路CAN总线,之前设计的是1.0版本,现在更新2.0版本设计书接上回,本次硬件工程师重新改了一版PCB,通过3588的4路SPI扩展出4路CAN。
RK3588 SPI 转CAN MCP251xCANFD
需求
需要4路CAN总线,之前设计的是1.0版本,现在更新2.0版本设计
RK3588外扩2路CAN【PCAN】【ch341】【XCAN】【SLCAN】试验
书接上回,本次硬件工程师重新改了一版PCB,通过3588的4路SPI扩展出4路CAN。
配置内核驱动
在内核kernel文件夹中,输入make menuconfig ARCH=arm64;
选择Networking support
选择CAN bus subsystem support
选择CAN Device Drivers
选择CAN SPI interfaces
选择Microchip MCP251xFD SPI CAN controllers
选择Additional Sanity Checks
使用空格将上面两项前面加上*号,选择save保存config文件
配置完成后进行确认


配置设备树
1.先看原理图(这个原理图有问题,后续更新最新的),使用SPI0、SPI1、SPI3、SPI4(理论上一路SPI即可扩4路,不过目前硬件这么设计,就按照这个改)



2.目前上面的原理图有问题:SPI的miso及mosi接反,中断引脚没连接;
通过上面原理图可以看到SPI管脚及其中的晶振是40MHz
3.更新后的原理图如下(待补充)
4.主要关注SPI管脚与中断管脚,结合飞凌给的《FET3588引脚复用对照表》进行查看,主要关注引脚复用情况与需要配置的管脚是否冲突,需要在设备树中进行屏蔽;
5.需要配置的设备树文件地址为:/home/forlinx/3588/OK3588_Linux_fs/kernel/arch/arm64/boot/dts/rockchip
需要配置的设备树名称为OK3588-C-common.dtsi
6.具体配置如下
- 在“/”下新增时钟频率节点,要匹配实际的晶振频率
1./ {
2.
3. /* 新增:MCP2518FD的40MHz固定晶振时钟(需与硬件晶振一致) */
4. mcp2518_clk: mcp2518-clk {
5. compatible = "fixed-clock";
6. #clock-cells = <0>;
7. clock-frequency = <40000000>;/* 时钟频率:40MHz */
8. };
9....
- 在下方增加SPI配置,SPI转CAN模块上有的INT脚是模块的中断引脚,在适配时需要连接一个可控的GPIO引脚作为中断脚,在SPI节点下添加匹配MCP2518驱动的设备树信息,compatible信息不能出错,这是匹配驱动的重要属性;SPI的片选也需要设置对应引脚
1.&spi0 {
2. pinctrl-names = "default";
3. pinctrl-0 = <&spi0m3_cs0 &spi0m3_pins>;
4. status = "okay";
5. spi@0 {
6. compatible = "microchip,mcp2518fd";
7. reg = <0>;
8. clocks = <&mcp2518_clk>;
9. pinctrl-names = "default";
10. pinctrl-0 = <&mcp2518_irq_pins_0>;
11. spi-max-frequency = <20000000>;
12. interrupts-extended= <&gpio0 RK_PD0 IRQ_TYPE_LEVEL_LOW>;
13. };
14.};
15.
16.&spi1 {
17. pinctrl-names = "default";
18. pinctrl-0 = <&spi1m2_cs0 &spi1m2_pins>;
19. status = "okay";
20. spi@0 {
21. compatible = "microchip,mcp2518fd";
22. reg = <0>;
23. clocks = <&mcp2518_clk>;
24. pinctrl-names = "default";
25. pinctrl-0 = <&mcp2518_irq_pins_1>;
26. spi-max-frequency = <20000000>;
27. interrupts-extended= <&gpio3 RK_PC0 IRQ_TYPE_LEVEL_LOW>;
28. };
29.};
30.
31.&spi3 {
32. pinctrl-names = "default";
33. pinctrl-0 = <&spi3m3_cs0 &spi3m3_pins>;
34. status = "okay";
35. spi@0 {
36. compatible = "microchip,mcp2518fd";
37. reg = <0>;
38. clocks = <&mcp2518_clk>;
39. pinctrl-names = "default";
40. pinctrl-0 = <&mcp2518_irq_pins_3>;
41. spi-max-frequency = <20000000>;
42. interrupts-extended= <&gpio0 RK_PC7 IRQ_TYPE_LEVEL_LOW>;
43. };
44.};
45.
46.&spi4 {
47. pinctrl-names = "default";
48. pinctrl-0 = <&spi4m0_cs0 &spi4m0_pins>;
49. status = "okay";
50. spi@0 {
51. compatible = "microchip,mcp2518fd";
52. reg = <0>;
53. clocks = <&mcp2518_clk>;
54. pinctrl-names = "default";
55. pinctrl-0 = <&mcp2518_irq_pins_4>;
56. spi-max-frequency = <20000000>;
57. interrupts-extended= <&gpio0 RK_PD3 IRQ_TYPE_LEVEL_LOW>;
58. };
- 在pinctrl中增加中断引脚;
1.&pinctrl {
2.
3. mcp2518 {
4. mcp2518_irq_pins_0: mcp2518-irq-pins-0 {
5. rockchip,pins = <0 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
6. };
7. mcp2518_irq_pins_1: mcp2518-irq-pins-1 {
8. rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
9. };
10. mcp2518_irq_pins_3: mcp2518-irq-pins-3 {
11. rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
12. };
13. mcp2518_irq_pins_4: mcp2518-irq-pins-4 {
14. rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
15. };
16. };
17....
- 去除相关引脚复用冲突如GPIO0_D0、GPIO0_D3;在原先配置中加入status = “disabled”;(复用冲突可以在飞凌给的《FET3588引脚复用对照表》进行查看)

- 关闭原生CAN在原先配置中加入status = “disabled”;

7.tips:修改设备树之前可备份一个副本; - 修改完成后可通过diff文件查看修改内容,diff -N -u -a OK3588-C-common.dtsi OK3588-C-common.dtsi_old > file.patch
- 修改内容一目了然,如下图





编译烧写
将以上驱动及设备树配置好后,编译内核烧写进开发板就可以测试了。
可以在源码目录中单独编译kernel;烧写编译生成的boot.img文件
通过烧写工具烧写替换即可
功能测试
- 在开发板中输入ifconfig -a命令查看can节点。

- 输入dmesg | grep mcp查看mcp2518加载与CAN设备对应情况

- 可以看到spi0为CAN0、spi1为CAN1、spi3为CAN2、spi4为CAN3;
通过命令进行CAN测试,我这里懒得每次开机都敲命令,简单写个脚本
- 如果要使用fd改为sudo ip link set can0 type can bitrate 500000 dbitrate 2000000 fd on
- 也可输入ip -d link show can0查看CAN设备配置情况;
- candump:
candump可以实时显示接收到的can消息。例:candump can0 - cansend:
cansend可以将单个CAN帧发送到总线上。您将必须指定设备,标识符和要发送的数据字节,例:cansend can0 123#1122334455667788 - cangen:
cangen可以生成随机的CAN数据,这对于测试很有用,例如,can0间隔100ms发一帧64位的随机CAN FD数据:例:cangen can0 -f -g 100 -L 64; - cansniffer:
cansniffer可以显示总线上接收到的CAN消息,而且可以过滤掉数据不变的帧。这对于逆向工程CAN总线系统非常有用。例:cansniffer -c can0 - canbusload:
canbusload可以用于实时显示处于工作状态(link up)的CAN设备的当前负载率。 例:canbusload can0@100000 can1@500000,2000000 can2@500000 -r -t -b -c
遇到的坑(可以忽略)
- 目前启动后驱动无法正常加载,ifconfig -a看不到can设备(因为硬件没连接中断管脚,设备树中直接找了一个没用到的GPIO,随便试试)

- 在设备树中去除中断配置(再试试),打印信息如下
这里说下,硬件说这个芯片不用中断也可以工作(采用轮询方式),故去除中断配置
- 后续与飞凌沟通,说让连接中断,硬件飞线连接GPIO后报错

- 经过排除及咨询飞凌技术支持,发现硬件SPI线序接反,让硬件工程师飞线后进行测试,问题排除

参考
OK3562 5.10.196 适配MCP2518CANFD
玩转Linux CAN/CAN FD—SocketCAN的使用-CSDN博客
[嵌入式linux]CAN/CAN FD配置及测试_linux canfd-CSDN博客
MCP251xFD芯片手册
mcp2518fd官网
懒人直接下载我整理好的资源,通过沉浸式翻译插件进行双语、中文版本手册
MCP25XXFD-CAN芯片手册
更多推荐


所有评论(0)