一.SPI理論介紹
SPI總線全名,串行外圍設備接口,是一種串行的主從接口,集成於很多微控制器內部。和I2C使用2根線相比,SPI總線使用4根線:MOSI (SPI 總線主機輸出/ 從機輸入)、 MISO (SPI總線主機輸入/從機輸出)、SCLK(時鐘信號,由主設備產生)、CS(從設備使能信號,由主設備控制)。由於SPI總線有專用的數據線用於數據的發送和接收,因此可以工作於全雙工,當前市面上可以找到的SPI外圍設備包括RF芯片、智能卡接口、E2PROM、RTC、觸摸屏傳感器、ADC。
SCLK信號線只由主設備控制,從設備不能控制信號線。同樣,在一個基於SPI的設備中,至少有一個主控設備。這樣傳輸的特點:這樣的傳輸方式有一個優點,與普通的串行通訊不同,普通的串行通訊一次連續傳送至少8位數據,而SPI允許數據一位一位的傳送,甚至允許暫停,因為SCLK 時鐘線由主控設備控制,當沒有時鐘跳變時,從設備不采集或傳送數據。也就是說,主設備通過對SCLK時鐘線的控制可以完成對通訊的控制。SPI還是一個數據交換協議:因為SPI的數據輸入和輸出線獨立,所以允許同時完成數據的輸入和輸出。不同的SPI設備的實現方式不盡相同,主要是數據改變和采集的時間不同,在時鐘信號上沿或下沿采集有不同定義,具體請參考相關器件的文檔。在點對點的通信中,SPI接口不需要進行尋址操作,且為全雙工通信,顯得簡單高效。在多個從設備的系統中,每個從設備需要獨立的使能信號,硬件上比I2C 系統要稍微復雜一些。
二.SPI驅動移植
我們下面將的驅動的移植是針對Mini2440的SPI驅動的移植
Step1 :在Linux Source Code中修改arch/arm/mach-s3c2440/mach-mini2440.c文件,加入頭文件:
#include <linux/spi/spi.h>
#include <../mach-s3c2410/include/mach/spi.h>
然後加入如下代碼:
static struct spi_board_info s3c2410_spi0_board[] =
{
[0] = {
.modalias = "spidev", //設備的名稱用來和驅動進行匹配
.bus_num = 0, //總線的編號,實際指對應的SPI寄存器
.chip_select = 0, //反映了這個芯片是不是被連接到SPI上
.irq = IRQ_EINT9, //設備的中斷號
.max_speed_hz = 500 * 1000, //SPI的最大速率
}
};
static struct s3c2410_spi_info s3c2410_spi0_platdata = {
.pin_cs = S3C2410_GPG(2),
.num_cs = 1, //所有的片選信號
.bus_num = 0, //SPI多對應的總線編號
.gpio_setup = s3c24xx_spi_gpiocfg_bus0_gpe11_12_13, //引腳設置函數
};
static struct spi_board_info s3c2410_spi1_board[] =
{
[0] = {
.modalias = "spidev",
.bus_num = 1,
.chip_select = 0,
.irq = IRQ_EINT2,
.max_speed_hz = 500 * 1000,
}
};
static struct s3c2410_spi_info s3c2410_spi1_platdata = {
.pin_cs = S3C2410_GPG(3),
.num_cs = 1,
.bus_num = 1,
.gpio_setup = s3c24xx_spi_gpiocfg_bus1_gpg5_6_7,
};
Step2:在mini2440_devices[]平台數組中添加如下代碼:
&s3c_device_spi0,
&s3c_device_spi1,
Step3:最後在mini2440_machine_init函數中加入如下代碼:
s3c_device_spi0.dev.platform_data= &s3c2410_spi0_platdata;
spi_register_board_info(s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board));
s3c_device_spi1.dev.platform_data= &s3c2410_spi1_platdata;
spi_register_board_info(s3c2410_spi1_board, ARRAY_SIZE(s3c2410_spi1_board));
Step4:最後需要修改arch/arm/plat-s3c24xx/KConfig文件
找到
config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
bool
help
SPI GPIO configuration code for BUS0 when connected to
GPE11, GPE12 and GPE13.
config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
bool
help
SPI GPIO configuration code for BUS 1 when connected to
GPG5, GPG6 and GPG7.
修改為
config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
bool "S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13"
help
SPI GPIO configuration code for BUS0 when connected to
GPE11, GPE12 and GPE13.
config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
bool "S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7"
help
SPI GPIO configuration code for BUS 1 when connected to
GPG5, GPG6 and GPG7.
Step5:最後make menuconfig配置,選中System Type和SPI support相應文件
Step6:執行make生成zInage,將編譯好的內核導入開發板,並且編譯測試程序運行即可。
好了,我們的SPI驅動移植就做好了,我們可以編寫SPI測試代碼進行測試。