# 如何使用linux內核提供SPI設備驅動Spidev 本文以Beaglebone版子為例,linux 4.19.142 系統移植請參閱 [beaglebone black wireless開發板系統移植](https://hackmd.io/@amberchung/install-beaglebone) ## Spidev驅動代碼移植 ### 1. 檢查kernal是否有build spidev驅動 進入beaglebone版子kernal目錄 cd bb-kernal/KERNAL 選擇spidev驅動 make menuconfig ``` Device Drivers -> <*>SPI support -> <*>User mode SPI device driver support or <M>User mode SPI device driver support ``` 目前beaglebone使用的spi driver是選用module方式,為了節省時間而選擇不重新編譯 ### 2. 修改device tree 進入bb-kernal/KERNAL 修改arch/arm/boot/dts/am335x-boneblack-wireless.dts文件 在&am33xx_pinmux裡增加SPI腳位定義 **注意:底下四個SPI使用的PIN必須設定為INPUT,否則SPI不會正常動作!!!** ``` spi0_pins_default: spi0_pins_default { pinctrl-single,pins = < AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, PIN_INPUT_PULLUP, MUX_MODE0) /* SPI0_CS0 */ AM33XX_PADCONF(AM335X_PIN_SPI0_D1, PIN_INPUT_PULLUP, MUX_MODE0) /* SPI0_D1 */ AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_INPUT_PULLUP, MUX_MODE0) /* SPI0_D0 */ AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_INPUT_PULLUP, MUX_MODE0) /* SPI0_SCLK */ >; }; ``` 以及定義spi相關設定,並引用上面定義的spi0_pins_default腳位定義 compatible需設定為"spidev",與spidev.c裡定義的相同 ![](https://static.coderbridge.com/img/chiyaonumber7/4677156a27cc4815a59c213122acf672.png) ``` &spi0 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&spi0_pins_default>; spidev0: spi@0 { compatible = "spidev"; reg = <0>; /*CS0*/ spi-max-frequency = <40000000>; }; }; ``` 建立新的設備樹 make dtbs 將新建立好的設備樹am335x-boneblack-wireless.dts複製到beaglebone上 ## beaglebone版子安裝spidev driver 將前面製作好的am335x-boneblack-wireless.dts複製到beaglebone開機會載入設備樹的位置,例如:/boot/dtbs/4.19.142-bone56/ 因選用module(M)模式,故若要使用每次開機皆須安裝 insmod /lib/modules/4.19.142-bone56/kernel/drivers/spi/spidev.ko 反之,若有選用y則不必安裝module 檢查是否成功載入spidev driver ls /dev/spidev*.* =>若有此目錄表示驅動與設備配對成功 Spidev驅動說明可以參見Kernal裡的Documentation\spi\spidev 而關於spi子系統完整說明請參考Kernal裡的Documentation\spi\spi-summary ## APP應用程序要如何使用呢? 可以參考linux內核裡tools/spi/spidev_test.c提供的範例,調用open/ioctrl/read/write/close等API函數進行SPI測試驗證 這裡簡單描述一下各個API的主要功能 * open:開啟設備 * ioctrl:根據底下傳入的參數做相對應的操作 1. 可讀取或寫入spi相關設定 * SPI_IOC_WR_MODE:寫模式 * SPI_IOC_RD_MODE:讀模式 * SPI_IOC_WR_BITS_PER_WORD:設置每個byte的有效位 * SPI_IOC_RD_BITS_PER_WORD:讀取設置的每個byte的有效位 * SPI_IOC_WR_MAX_SPEED_HZ:設置spi最大速度 * SPI_IOC_RD_MAX_SPEED_HZ:讀取設置的spi最大速度 * SPI_IOC_WR_LSB_FIRST:設置為最低位元傳送或接收 * SPI_IOC_RD_LSB_FIRST:讀取設置的spi最低位元 2. spi資料傳送接收 * SPI_IOC_MESSAGE(n):n為傳送的數量 * write:只傳送不接收spi資料 * read:只接收不傳送spi資料 * close:關閉設備