新聞中心

SPI驅(qū)動(dòng)的移植

作者: 時(shí)間:2016-11-10 來(lái)源:網(wǎng)絡(luò) 收藏
為了使用SPI 驅(qū)動(dòng),必須在配置Linux 編譯選項(xiàng)時(shí),開(kāi)啟相應(yīng)的SPI 選項(xiàng),如下所示
-> Device Drivers
-> SPI support
SPI support
*** SPI Master Controller Drivers ***
-*- Bitbanging SPI master
<*> Samsung S3C24XX series SPI
< > Samsung S3C24XX series SPI by GPIO
*** SPI Protocol Masters ***
< > SPI EEPROMs from most vendors
<*> User mode SPI device driver support
< > Infineon TLE62X0 (for power switching)
選擇SPI support 是使Linux內(nèi)核提供SPI 支持,選擇該選項(xiàng)會(huì)默認(rèn)選擇Bitbanging SPImaster,還需選擇SamsungS3C24XX series SPI,告訴內(nèi)核使用S3C2440A的SPI 控制器驅(qū)動(dòng)。

首先在 devs.c中,增加板子信息
  1. /* 2009/06/30 jwpan add by spi begin */
  2. static struct spi_board_info s3c2410_spi0_board[] = {
  3. [0] = {
  4. .modalias = "spidev", /*跟spidev.ko驅(qū)動(dòng)名要相同,不然掛載不上*/
  5. .platform_data = NULL,
  6. .bus_num = 0, /*使用的第一條BUS線,2410支持0,1兩根*/
  7. .chip_select = 1, /*片選信號(hào),和上面結(jié)合,在/dev 里面可以看到spidev0.1*/
  8. .max_speed_hz = 500*1000, /CLK頻率*/
  9. },
  10. };
  11. static struct s3c2410_spi_info s3c2410_spi0_platdata = {
  12. .pin_cs = S3C2410_GPB1,
  13. .board_info = s3c2410_spi0_board,
  14. .board_size = ARRAY_SIZE(s3c2410_spi0_board),
  15. };
  16. /* 2009/06/30 jwpan add by spi end */
復(fù)制代碼
  1. struct platform_device s3c_device_spi0 = {
  2. .name = "s3c2410-spi",
  3. .id = 0,
  4. .num_resources = ARRAY_SIZE(s3c_spi0_resource),
  5. .resource = s3c_spi0_resource,
  6. .dev = {
  7. .dma_mask = &s3c_device_spi0_dmamask,
  8. /* 2009/06/30 jwpan add by spi begin */
  9. //.coherent_dma_mask = 0xffffffffUL
  10. .coherent_dma_mask = 0xffffffffUL,
  11. .platform_data = &s3c2410_spi0_platdata,
  12. /* 2009/06/30 jwpan add by spi end */
  13. }
  14. };
復(fù)制代碼增加初始化代碼,也可以加到mach-smdk2410.c里面
  1. static struct platform_device __initdata *smdk_devs[] = {
  2. &s3c_device_nand,
  3. &smdk_led4,
  4. &smdk_led5,
  5. &smdk_led6,
  6. &smdk_led7,
  7. /* 2009/06/30 jwpan add by dm9000 spi begin */
  8. &s3c_device_spi0,
  9. /* 2009/06/30 jwpan add by dm9000 spi end */
  10. };
復(fù)制代碼在spi.c的spi_register_master函數(shù)里面,有這么一個(gè)判斷:
  1. if(master->num_chipselect == 0)
  2. return -EINVAL;
復(fù)制代碼本以為master->num_chipselect這個(gè)值可以通過(guò)硬件檢測(cè)拿到,或者驅(qū)動(dòng)有這樣的設(shè)置.
萬(wàn)萬(wàn)沒(méi)有想到,這個(gè)值就是沒(méi)有初始化.

需要在spi_s3c24xx.c里面增加一句代碼:
  1. hw->bitbang.txrx_bufs = s3c24xx_spi_txrx;
  2. hw->bitbang.master->num_chipselect = 2;/* add */
  3. dev_dbg(hw->dev,"bitbang at %pn",hw->bitbang);
復(fù)制代碼另外,在 *spi_new_device函數(shù)里面,還有一個(gè)判斷的bug,num_chipselect也是從0開(kāi)始的,>=的話就不對(duì)了.
  1. //if (chip->chip_select >= master->num_chipselect) {
  2. if (chip->chip_select > master->num_chipselect) {
復(fù)制代碼編譯內(nèi)核,啟動(dòng)后可以在/dev/下面看到spidev.0.1

之后,就可以使用spidev_test ,spidev_fdx程序進(jìn)行測(cè)試了,這兩個(gè)文件在linux2.6.30的Documentation/Spi目錄下面有。

最后,提示一下:
I2C/SPI支持“線與”,允許多個(gè)設(shè)備互連。所以協(xié)議規(guī)定:在無(wú)數(shù)據(jù)傳輸(開(kāi)始前、結(jié)束后)時(shí),時(shí)鐘和數(shù)據(jù)線都處于“釋放”狀態(tài),也就是“高阻”狀態(tài)。
在“釋放”狀態(tài),如果有上拉電阻(內(nèi)部或外部的),用外用表測(cè)會(huì)是高電平(1);如果沒(méi)有上拉電阻,用萬(wàn)用表測(cè)是低電平(0)。

簡(jiǎn)單一點(diǎn)就是說(shuō):SPI的CLK只有在有數(shù)據(jù)通信時(shí),才會(huì)測(cè)得出波形,千萬(wàn)別以為SPI出問(wèn)題了。


關(guān)鍵詞: SPI驅(qū)動(dòng)移

評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉