寫在前面
在文章“嵌入式Linux的CAN匯流排配置——基於迅為iTOP-4412開發板”中我給4412開發板配置了SPI轉CAN模組,使用的是不帶裝置樹的核心。在本篇文章中,要使用支援裝置樹的核心,給iMX6UL開發板配置MCP2515。
開啟iMX6UL開發板的串列埠終端,輸入命令ifconfig -a
,可以看到CAN0和CAN1兩個裝置,這是iMX6UL晶片自帶的兩路FlexCAN。
在完成配置MCP2515模組之後,輸入命令ifconfig -a
,可以看到三路CAN,其中CAN1和CAN2是iMX6UL晶片自帶的兩路FlexCAN,而CAN0便是通過MCP2515實現的SPI轉CAN。
硬體連線
將SPI轉CAN模組插到iMX6UL開發板的GPIO插槽上。
需要注意的是,該GPIO插槽中的PIN腳沒有支援ECSPI的,所以我們在這裡用的SPI是把相應的PIN腳用軟體模擬出的SPI。
通過檢視GPIO插槽和SPI轉CAN的原理圖,可以知道MCP2515和GPIO插槽上PIN腳的對應關係。共需要五個PIN腳,分別是SPI_SCK,SPI_CS,SPI_MOSI,SPI_MISO,以及中斷引腳MCP2515_INT。
再檢視核心板的文件,可以獲得MCP2515的這五個腳和iMX6UL晶片PIN腳的對應關係,如下表所示。
MCP2515 | iMX6UL |
---|---|
SPI_SCK | GPIO5_IO11 |
SPI_CS | GPIO1_IO09 |
SPI_MOSI | GPIO5_IO10 |
SPI_MISO | GPIO3_IO07 |
MCP2515_INT | GPIO1_IO31 |
# 修改裝置樹
進入核心目錄,使用命令`vim Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt`開啟關於MCP2515的裝置樹幫助文件。
可以根據該幫助文件的提示資訊來仿寫一個CAN節點。
再開一個終端,進入核心目錄,使用命令vim arch/arm/boot/dts/imx6ul-14x14-evk_emmc.dts
開啟開發板對應的裝置樹檔案(裝置樹檔案可能會因開發板型號的不同而不同,請開啟你的開發板對應的裝置樹檔案)。在裝置樹的根節點下,可以看到一個名為“spi4”的裝置節點,這個節點對應的就是模擬SPI。
①首先在“spi4”節點前增加一個時鐘節點,如下圖所示。
clocks {
mcp2515_clock: mcp2515_clock {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <8000000>; //對應模組上晶振的頻率,我的是8MHz的
};
};
②然後對“spi4”節點做修改,並刪除它的子節點“gpio_spi”,然後根據幫助文件自己寫一個“can0”節點作為“spi4”節點的子節點,如下圖所示(註釋部分為所做的修改或新增)。
spi4 {
compatible = "spi-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi4>;
//pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;//這個引腳用不到
status = "okay";
gpio-sck = <&gpio5 11 0>;
gpio-mosi = <&gpio5 10 0>;
gpio-miso = <&gpio3 7 0>; //增加SPI_MISO引腳
//cs-gpios = <&gpio5 7 0>;
cs-gpios = <&gpio1 9 0>; //修改SPI_CS對應的引腳
num-chipselects = <1>;
#address-cells = <1>;
#size-cells = <0>;
can0: can0@1 {
compatible = "microchip,mcp2515";
reg = <0>; //地址從0開始
clocks = <&mcp2515_clock>; //使用剛剛自己寫的時鐘
interrupt-parent = <&gpio1>; //中斷引腳配置,中斷引腳是GPIO1_IO31
interrupts = <31 0x2>; //中斷引腳配置,中斷引腳是GPIO1_IO31,引數0x2表示觸發方式
vdd-supply = <®_can_3v3>; //使用3.3V供電
xceiver-supply = <®_can_3v3>; //使用3.3V供電
spi-max-frequency = <1000000>; //最後增加spi最大頻率設定,設定為1MHz
};
};
③找到節點“pinctrl_spi4”,在該節點中新增SPI_CS和SPI_MISO相關的引腳,如下圖所示(有註釋的部分為所做的新增)。
pinctrl_spi4: spi4grp {
fsl,pins = <
MX6UL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
MX6UL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x80000000 /*SPI_CS*/
MX6UL_PAD_LCD_DATA02__GPIO3_IO07 0x70a1 /*SPI_MISO*/
>;
};
④搜尋“gpio1 9”和“GPIO1_IO09”,註釋掉裝置樹檔案自帶的和GPIO1_IO09引腳相關的內容(因為這個腳被我們用做SPI_CS了),如下圖所示。
⑤搜尋“I2C2_SCL”、“LCD_DATA00”、“LCD_DATA02”,註釋掉裝置樹原有的相關語句,如下圖所示。
⑥搜尋“spi_gpio”,把所有和“spi_gpio”相關的語句全部註釋掉,否則會編譯出錯(因為節點“spi_gpio”已經被刪除了),如下圖所示。
⑦然後分別進入裝置樹檔案“arch/arm/boot/dts/topeet_emmc_4_3.dts”、“arch/arm/boot/dts/topeet_emmc_5_0.dts”、“arch/arm/boot/dts/topeet_emmc_7_0.dts”、“arch/arm/boot/dts/topeet_emmc_9_7.dts”、“arch/arm/boot/dts/topeet_emmc_10_1.dts”、“arch/arm/boot/dts/topeet_emmc_1024x600.dts”這六個裝置樹檔案,刪除“gpio_spi”相關的語句,如下圖所示。
裁剪核心
進入核心根目錄下,使用命令export ARCH=arm
,指定架構。然後使用命令make menuconfig
進入核心裁剪介面。
①進入“Device Drivers--->SPI support--->”,選中“GPIO-based bitbanging SPI Master”和“Freescale i.MX SPI controllers ”
②然後進入“Networking support--->CAN bus subsystem support--->CAN Device Drivers--->CAN SPI interfaces--->”,選中“Microchip MCP251x SPI CAN controllers”。
儲存,並退出。
編譯和燒寫
編譯核心和裝置樹,並將編譯出來的核心和裝置樹檔案燒寫到開發板中。重啟裝置,MCP2515裝置便可以使用了。
目前存在的問題
每次裝置重啟後,第一次使用命令ifconfig can0 up
啟動MCP2515會提示沒有該裝置,再啟動一次就能正常啟動了。
裝置樹原始碼在這裡,下載下來後覆蓋掉“arch/arm/boot/dts/”路徑下相應的dts檔案即可。