作者:​​三点水兽​

 




参考一:

 

按照下面帖子的方法,本人试验成功,只需按照下面步骤进行就行了。

注:原文最后短接的MISO和MOSI指的是SPI1的,区别于SPI0

 

mini2440中,SPI0和SPI1的四个功能引脚均接有上拉电阻10K到3.3V。


引脚



SPICLK0



SPIMISO0



SPIMOSI0



nSS0/GPG2/EINT10



复用功能



GPE13



GPE11



GPE12



Only for slave mode P23



CON4 引脚



27



25



26



28


SPI1同时接到开发板上的按键


引脚



SPICLK1



SPIMISO1



SPIMOSI1



nSS1/GPG3/EINT11



复用功能



GPG7/EINT15



GPG5/EINT13



GPG6/EINT14



Only for slave mode P23



CON4 引脚



21



19



20



18



---------------------------------------------------------------------------------- 分隔线---------------------------------------------

最近项目需要,需要在mini2440上移植SPI驱动,板子需要驱动SPI设备,上网找了很多资源,但是很多都是有问题,最终在基本理解驱动结构的前提下,将SPI驱动顺利移植到mini2440。

,我使用的内核版本是2.6.32.2,这个版本和2.6。29不一样,网上很多版本都是关于2.6.29,如果完全按照网上步骤,编译会出现问题,我做的步骤如下:

1,在Linux Source Code中修改arch/arm/mach-s3c2440/mach-mini2440.c文件,加入头文件:

 




​view plain​


  1. #include   
  2. #include <../mach-s3c2410/include/mach/spi.h>  

然后加入如下代码:

 




​view plain​


  1. static struct spi_board_info s3c2410_spi0_board[] =  
  2. {  
  3.         [0] = {  
  4.                 .modalias = "spidev",  
  5.                 .bus_num = 0,  
  6.                 .chip_select = 0,  
  7.                 .irq = IRQ_EINT9,  
  8.                 .max_speed_hz = 500 * 1000,  
  9.                 }  
  10. };  
  11.   
  12. static struct s3c2410_spi_info s3c2410_spi0_platdata = {  
  13.         .pin_cs = S3C2410_GPG(2),  
  14.         .num_cs = 1,  
  15.         .bus_num = 0,  
  16.         .gpio_setup = s3c24xx_spi_gpiocfg_bus0_gpe11_12_13,  
  17. };  
  18.   
  19. static struct spi_board_info s3c2410_spi1_board[] =  
  20. {  
  21.         [0] = {  
  22.                 .modalias = "spidev",  
  23.                 .bus_num = 1,  
  24.                 .chip_select = 0,  
  25.                 .irq = IRQ_EINT2,  
  26.                 .max_speed_hz = 500 * 1000,  
  27.                 }  
  28. };  
  29.   
  30.   
  31. static struct s3c2410_spi_info s3c2410_spi1_platdata = {  
  32.         .pin_cs = S3C2410_GPG(3),  
  33.         .num_cs = 1,  
  34.         .bus_num = 1,  
  35.         .gpio_setup = s3c24xx_spi_gpiocfg_bus1_gpg5_6_7,  
  36. };  

这里需要了解驱动架构,其中移植过程中容易出问题的地方时S3C2410_GPG(2)和S3C2410_GPG(3)两处地方,网上一般给的源代码是 S3C2410_GPG2,这在2.6.29中可行,但是在2.6.32源代码中没有定义S3C2410_GPG2宏定义,要使用 S3C2410_GPG(2)宏定义。

在mini2440_devices[]平台数组中添加如下代码:

 




​view plain​


  1. &s3c_device_spi0,  
  2. &s3c_device_spi1,  

最后在mini2440_machine_init函数中加入如下代码:

 




​view plain​


  1. s3c_device_spi0.dev.platform_data= &s3c2410_spi0_platdata;  
  2. spi_register_board_info(s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board));  
  3. s3c_device_spi1.dev.platform_data= &s3c2410_spi1_platdata;  
  4. spi_register_board_info(s3c2410_spi1_board, ARRAY_SIZE(s3c2410_spi1_board));  


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

找到如下代码段:

 




​view plain​


  1. config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13  
  2.         bool   
  3.         help  
  4.           SPI GPIO configuration code for BUS0 when connected to  
  5.           GPE11, GPE12 and GPE13.  
  6.   
  7. config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7  
  8.         bool   
  9.         help  
  10.           SPI GPIO configuration code for BUS 1 when connected to  
  11.           GPG5, GPG6 and GPG7.  


修改为



​view plain​


  1. config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13  
  2.         bool "S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13"  
  3.         help  
  4.           SPI GPIO configuration code for BUS0 when connected to  
  5.           GPE11, GPE12 and GPE13.  
  6.   
  7. config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7  
  8.         bool "S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7"  
  9.         help  
  10.           SPI GPIO configuration code for BUS 1 when connected to  
  11.           GPG5, GPG6 and GPG7.  

最后我们配置编译文件:

 




​view plain​


  1. make menuconfig  

图1

图2

图3

图4

图5

最后编译内核




​view plain​


  1. make zImage  

将编译好的内核导入开发板,并且编译Linux Source自带的测试程序,在Documentation/spi下,修改spidev_test.c文件,将device name改为/dev/spidev1.0

交叉编译:

 




​view plain​


  1. arm-linux-gcc -I ~/linux-2.6.32.2/include/ spidev_test.c  

将编译好的文件下载到开发板上,并且将开发板的SPI MOI和MIO短接,也就是让SPI自己发送自己接收,执行文件,我们看到如下结果:

 




​view plain​


  1. FF FF FF FF FF FF  
  2. 40 00 00 00 00 95  
  3. FF FF FF FF FF FF  
  4. FF FF FF FF FF FF  
  5. FF FF FF FF FF FF  
  6. DE AD BE EF BA AD  
  7. F0 0D  

说明驱动移植成功。

 

总结:这里叙述的是驱动移植详细过程,代码的具体含义以及开发板的针脚对应图需要自己去查阅相关资料,这里不再详述。

 

 

参考二:


转载:http://blog.chinaunix.net/uid-23095063-id-3154633.html



近段时间在调试S3C2440板卡上SPI的驱动程序,主要是利用2440的SPI0控制一块BCM交换芯片 (slave),本来想自己手写一个SPI驱动,但看了看linux 2.6.29内核里已经自带了2440的SPI驱动,所以就直接利用了内核自带的驱动,过程如下:

    第一步:在编译内核make menuconfig时选上进入驱动选项页;

mini2440 SPI驱动移植 (基于SPI子系统) (转的记录)_3c

    第二步:在驱动选项页里选择SPI,进入SPI页;

    第三步:选择上图带*号的选项,保存并退出配置界面;

    第四步:修改arch/arm/mach-s3c2440/mach-mini2440.c文件,在include头文件代码行之后增加如下代码

//add spi

#include 

#include

static struct spi_board_info s3c2410_spi0_board[] = {

        [0] = {

                 .modalias = "spidev",

                .bus_num        = 0, 

                .chip_select        = 0,

                .irq = IRQ_EINT9,

                .max_speed_hz         = 500*1000,

        },

};

//.pin_cs = S3C2410_GPB1,

static struct s3c2410_spi_info s3c2410_spi0_platdata = {

        .pin_cs = S3C2410_GPG2,

        .num_cs = 1,

        .bus_num = 0,

};

//end add spi

    这里需要注意的是片选管脚.pin_cs需要根据自己的硬件实际情况来定义,我的板卡用的是GPG2管脚作为片选。

    然后在函数__init mini2440_machine_init的开头增加下列代码

//add spi

s3c_device_spi0.dev.platform_data= &s3c2410_spi0_platdata;

spi_register_board_info(s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board));

//end spi

    第五步:修改drivers/spi/spi_s3c24xx.c文件,在s3c24xx_spi_initialsetup函数结尾增加下列代码

s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT);

s3c2410_gpio_cfgpin(0x8B, S3C2410_GPIO_SFN2);

s3c2410_gpio_cfgpin(0x8C, S3C2410_GPIO_SFN2);

s3c2410_gpio_cfgpin(0x8D, S3C2410_GPIO_SFN2);

    主要是为了防止有些板卡在硬件复位之后2440寄存器没有完全复位成默认值,所以需要手动进行配置;

    第六步:用make zImage编译内核。

    烧录新内核,板卡起来之后在/dev/目录下会产生一个新的设备文件spidev0.0,这时可以用内核自带的测试程序进行测试,内核测试程序在 Documentation/spi目录下,直接修改并编译spidev_test.c文件即可。测试时可以用一根导线将SPI的out和in两根管脚连 接起来形成环路——自发自收。这个测试程序有几个参数需要注意,

-D,这是让你选择spi设备名,我的是/dev/spidev0.0;

-s,选择速率,单位是Hz,默认是500000,一般可以设到2M;

-H,时钟相位,我的设备要求为1,即时钟信号为高时片选由高到低有效,默认为0,带该参数表示1;

-O,时钟极性,我的设备要求为1,即空闲时时钟信号要保持为高,默认为0,带该参数表示1;

-C,片选置高,我的设备要求0,即片选信号为低时有效,默认为0,带该参数表示1;

其它参数没有用过,不知道什么意思。当然如果是自发自收测试这些参数除了设备名外都可以不设置。

    其实SPI的原理很简单,主要有3根线(时钟,数据输入,数据输出),再加一个片选线,时钟始终由master发出,master发送字节的同时会产生时 钟信号,由于slave不能产生时钟,所以为了从slave接收数据,master必须在接收数据时也发送数据(可以为全0)以产生时钟。

    我在驱动里是用中断的方式来发送和接收数据的,每发送一个字节数据,产生一次中断,在中断里查看状态寄存器,并读取接收寄存器里的值,然后继续下一个字节的发送,如此循环直到全部发送和接收完毕。