基於S3C2440的嵌入式Linux驅動--SPI子系統圖解

1.SPI子系統框圖詳解:

    SPI總線上有兩類設備:一類是主控端,通常作爲SOC系統的一個子模塊出現,比如很多嵌入式MPU中都常常包含SPI模塊。一類是受控端,例如一些SPI接口的Flash、傳感器等等。主控端是SPI總線的控制者,通過使用SPI協議主動發起SPI總線上的會話。而受控端則被動接受SPI主控端的指令,並作出響應的響應



如圖1所示,linux下的spi子系統主要涉及3個部分:spi核心、spiprotocol驅動和spi主控制器驅動。如圖1.1spi核心負責抽象出所有控制器都具備的功能代碼,同時向上爲spiprotocol驅動提供接口比如spi_messagespi_transferspi_async等,具體可參見linux/spi/spi.h文件,需要自己寫客戶驅動的可以詳細瞭解一下spi.h文件。


spi控制器驅動負責與具體的控制器硬件溝通,進行bit級的數據傳輸。

spi客戶驅動,即protocol驅動負責從控制器端接收數據,然後按照“protocol”將其解釋爲有意義的數據格式


2則顯示了LinuxSPI子系統所涉及的大部分結構和函數調用,其中一些細節可以在這裏找到你想要得。


2. SPI驅動移植

   平臺:mini2440

    kernellinux-2.6.32.2

    MasterSPI0

    Slaveof

從圖2中我們看出,要進行驅動移植,大致要做的就是完成上面的6個主要結構的註冊,使系統能夠識別他們。

首先:在LinuxSource Code中修改arch/arm/mach-s3c2440/mach-mini2440.c文件,加入頭文件:

#include<linux/spi/spi.h>
#include<../mach-s3c2410/include/mach/spi.h>

接着是各個結構的註冊:

  1. s3c_device_spi0:在devs.c中定義,需要在板級文件mach-mini2440.cmini2440_devices[]平臺數組中添加如下代碼:

    &s3c_device_spi0,

    s3c2410_spi_info:就是s3c_device_spi0platform_data,用來初始化master,給出了總線有幾條,和其相連的slave數量,設置片選的函數...也需要在mach-mini2440.c中加入:

    static structs3c2410_spi_info s3c2410_spi0_platdata = {
        .pin_cs= S3C2410_GPG(2),//這個得看你的板子具體情形了
        .num_cs= 1, //有一個slave
        .bus_num= 0, //只有一條SPI總線
        .gpio_setup =s3c24xx_spi_gpiocfg_bus0_gpe11_12_13,
    };

    接着在mini2440_machine_init中加入:

    s3c_device_spi0.dev.platform_data=&s3c2410_spi0_platdata;

  1. controller的平臺驅動:s3c24xx_spi_driver,makemenuconfig時打開便好;

  2. 總線spi_bus_typespi核心,在makemenuconfig時打開便好;

  3. controller驅動:也不需要動;

  4. 板級設備信息,即你的slave和總線的連接:

    spi_board_info:在mach-mini2440.c中加入s3c2410_spi0_board,如下
    static structspi_board_info s3c2410_spi0_board[] = {
        [0] = {
            .modalias= "adns3080", //需要和你的驅動一致
            .bus_num= 0,
            .platform_data =&adns3080_data,
            .chip_select= 0,
            .irq =IRQ_EINT9,
            .max_speed_hz= 500 * 1000,
        }
    };

    外加頭文件(有必要的話):adns3080.h

    #ifndef __SPI_PLATFORM_ADNS3080_H__
    #define __SPI_PLATFORM_ADNS3080_H__
    struct adns3080_platform_data{
        your_data_0;
    };
    #endif
    static structadns3080_platform_data adns3080_data = {
        .your_data_0 =your_data,
    };

    接着在mini2440_machine_init中加入:

    spi_register_board_info(s3c2410_spi0_board,ARRAY_SIZE(s3c2410_spi0_board));

    6. my_driver:其實可以沒有my_driver這一步,這需要你自己寫的,在module_init中會註冊的...也可以使用kernel自帶的spidev.c驅動,這就需要打開SPIDEV的支持:

    makemenuconfig時:

    Device Drivers

        SPI support

            User mode SPIdevicedriver support //打開這一項

然後是板級信息:

7.接着就不是結構註冊,上面如果是板級,下面就得是芯片級了。配置文件的改動:

需要修改arch/arm/plat-s3c24xx/KConfig文件

找到如下代碼段:


configS3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
    bool
    help
    SPI GPIOconfiguration code for BUS0 when connected to GPE11, GPE12 andGPE13.
configS3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
    bool
    help
    SPI GPIOconfiguration code for BUS 1 when connected to GPG5, GPG6 andGPG7.
修改爲
configS3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
    bool"S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13" // 管腳可以看芯片手冊
    help
    SPI GPIOconfiguration code for BUS0 when connected to GPE11, GPE12 andGPE13.  //spi_bus0

configS3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
    bool"S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7"
    help
    SPI GPIOconfiguration code for BUS 1 when connected to GPG5,GPG6 and GPG7. //spi_bus1


最後的make menuconfig    ...         

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章